Ver código fonte

added window event handling

Zoadian 11 anos atrás
pai
commit
68b568d80a

+ 51 - 662
source/app.d

@@ -2,75 +2,12 @@ import std.stdio;
 
 import std.typecons;
 
-import derelict.opengl3.gl3;
-import derelict.glfw3.glfw3;
-import derelict.anttweakbar.anttweakbar;
-import derelict.freeimage.freeimage;	
-import derelict.freetype.ft;
-import derelict.assimp3.assimp;
-
-import std.string;
-import std.experimental.logger;
-
+import three;
 
+import std.experimental.logger;
 
-//======================================================================================================================
-// 
-//======================================================================================================================
-import std.traits : ReturnType;
-ReturnType!func glCheck(alias func, string file = __FILE__, size_t line = __LINE__, string mod = __MODULE__, string funcd = __FUNCTION__, string pretty = __PRETTY_FUNCTION__, Args...)(Args args) nothrow {
-	import std.stdio;
-	import std.stdio : stderr;
-	import std.array : join;
-	import std.range : repeat;
-	import std.string : format;
-	try{
-		debug scope(exit) {
-			GLenum err = glGetError();
-			if(err != GL_NO_ERROR) {
-				stderr.writeln("\n===============================");
-				stderr.writeln("File: ", file, "\nLine: ", line, "\nModule: ",mod, "\nFunction: ",funcd, "\n",pretty);
-				stderr.writeln("-------------------------------");
-				stderr.writefln(`OpenGL function "%s(%s)" failed: "%s."`, func.stringof, format("%s".repeat(Args.length).join(", "), args), glErrorString(err));
-				stderr.writeln("=============================== \n");
-				assert(false);
-			}
-		}
-	}
-	catch(Exception e){
-	}
-	
-	debug if(func is null) {
-		try{
-			stderr.writefln("%s is null! OpenGL loaded? Required OpenGL version not supported?".format(func.stringof));
-		}
-		catch(Exception e){
-			assert(false);
-		}
-		assert(false);
-	}	
-	return func(args);
-}
-
-string glErrorString(GLenum error) pure @safe nothrow @nogc {
-	final switch(error) {
-		case GL_NO_ERROR: return "no error";
-		case GL_INVALID_ENUM: return "invalid enum";
-		case GL_INVALID_VALUE: return "invalid value";
-		case GL_INVALID_OPERATION: return "invalid operation";
-			//case GL_STACK_OVERFLOW: return "stack overflow";
-			//case GL_STACK_UNDERFLOW: return "stack underflow";
-		case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffer operation";
-		case GL_OUT_OF_MEMORY: return "out of memory";
-	}
-	assert(false, "invalid enum");
-}
 
 
-//======================================================================================================================
-// 
-//======================================================================================================================
-alias SoA(T) = T[];
 
 //======================================================================================================================
 // 
@@ -89,603 +26,7 @@ struct SOAQuaternion {
 }
 
 
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct Window {
-private:
-	GLFWwindow* glfwWindow = null;
-	string title;
-	uint x, y, width, height;
-	KeyAction[int] keyStates;
-	ButtonAction[int] buttonStates;
-}
-
-alias ScanCode = int;
-
-enum IconifyAction {
-	Iconified,
-	Restored
-}
-
-enum FocusAction {
-	Focused,
-	Defocused
-}
-
-enum CursorAction {
-	Entered,
-	Leaved
-}
-
-enum ButtonAction {
-	Pressed,
-	Released
-}
-
-enum KeyAction {
-	Pressed,
-	Released,
-	Repeated
-}
-
-enum KeyMod {
-	Shift = 0x0001,
-	Control = 0x0002,
-	Alt = 0x0004,
-	Super = 0x0008,
-}
-
-enum Key {
-	Unknown = -1,
-	Space = 32,
-	Apostrophe = 39,
-	Comma = 44,
-	Minus = 45,
-	Period = 46,
-	Slash = 47,
-	Key0 = 48,
-	Key1 = 49,
-	Key2 = 50,
-	Key3 = 51,
-	Key4 = 52,
-	Key5 = 53,
-	Key6 = 54,
-	Key7 = 55,
-	Key8 = 56,
-	Key9 = 57,
-	Semicolon = 59,
-	Equal = 61,
-	KeyA = 65,
-	KeyB = 66,
-	KeyC = 67,
-	KeyD = 68,
-	KeyE = 69,
-	KeyF = 70,
-	KeyG = 71,
-	KeyH = 72,
-	KeyI = 73,
-	KeyJ = 74,
-	KeyK = 75,
-	Keyl = 76,
-	KeyM = 77,
-	KeyN = 78,
-	KeyO = 79,
-	KeyP = 80,
-	KeyQ = 81,
-	KeyR = 82,
-	KeyS = 83,
-	KeyT = 84,
-	KeyU = 85,
-	KeyV = 86,
-	KeyW = 87,
-	KeyX = 88,
-	KeyY = 89,
-	KeyZ = 90,
-	LeftBracket = 91,
-	Backslash = 92,
-	RightBracket = 93,
-	GraveAccent = 96,
-	World1 = 161,
-	World2 = 162,
-	Escape = 256,
-	Enter = 257,
-	Tab = 258,
-	Backspace = 259,
-	Insert = 260,
-	Delete = 261,
-	Right = 262,
-	Left = 263,
-	Down = 264,
-	Up = 265,
-	PageUp = 266,
-	PageDown = 267,
-	Home = 268,
-	End = 269,
-	CapsLock = 280,
-	ScrollLock = 281,
-	NumLock = 282,
-	PrintScreen = 283,
-	Pause = 284,
-	F1 = 290,
-	F2 = 291,
-	F3 = 292,
-	F4 = 293,
-	F5 = 294,
-	F6 = 295,
-	F7 = 296,
-	F8 = 297,
-	F9 = 298,
-	F10 = 299,
-	F11 = 300,
-	F12 = 301,
-	F13 = 302,
-	F14 = 303,
-	F15 = 304,
-	F16 = 305,
-	F17 = 306,
-	F18 = 307,
-	F19 = 308,
-	F20 = 309,
-	F21 = 310,
-	F22 = 311,
-	F23 = 312,
-	F24 = 313,
-	F25 = 314,
-	NumBlock0 = 320,
-	NumBlock1 = 321,
-	NumBlock2 = 322,
-	NumBlock3 = 323,
-	NumBlock4 = 324,
-	NumBlock5 = 325,
-	NumBlock6 = 326,
-	NumBlock7 = 327,
-	NumBlock8 = 328,
-	NumBlock9 = 329,
-	KpDecimal = 330,
-	KpDivide = 331,
-	KpMultiply = 332,
-	KpSubtract = 333,
-	KpAdd = 334,
-	KpEnter = 335,
-	KpEqual = 336,
-	LeftShift = 340,
-	LeftControl = 341,
-	LeftAlt = 342,
-	LeftSuper = 343,
-	RightShift = 344,
-	RightControl = 345,
-	RightAlt = 346,
-	RightSuper = 347,
-	Menu = 348
-}
-
-void construct(out Window window, string title, uint width, uint height) nothrow {
-	window.x = 0;
-	window.y = 0;
-	window.width = width;
-	window.height = height;
 
-	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
-	
-	glfwDefaultWindowHints();
-	glfwWindowHint(GLFW_RED_BITS, 8);
-	glfwWindowHint(GLFW_GREEN_BITS, 8);
-	glfwWindowHint(GLFW_BLUE_BITS, 8);
-	glfwWindowHint(GLFW_ALPHA_BITS, 0);
-	glfwWindowHint(GLFW_DEPTH_BITS, 24);
-	glfwWindowHint(GLFW_STENCIL_BITS, 8);
-	window.glfwWindow = glfwCreateWindow(width, height, title.toStringz(), null, null);
-	assert(window.glfwWindow !is null);
-
-//	glfwSetWindowUserPointer(window.glfwWindow, cast(void*)&window);
-//	glfwSetWindowPosCallback(window.glfwWindow, cast(GLFWwindowposfun)&_GLFWwindowposfun);
-//	glfwSetWindowSizeCallback(window.glfwWindow, cast(GLFWwindowsizefun)&_GLFWwindowsizefun);
-//	glfwSetWindowCloseCallback(window.glfwWindow, cast(GLFWwindowclosefun)&_GLFWwindowclosefun);
-//	glfwSetWindowRefreshCallback(window.glfwWindow, cast(GLFWwindowrefreshfun)&_GLFWwindowrefreshfun);
-//	glfwSetWindowIconifyCallback(window.glfwWindow, cast(GLFWwindowiconifyfun)&_GLFWwindowiconifyfun);
-//	glfwSetMouseButtonCallback(window.glfwWindow, cast(GLFWmousebuttonfun)&_GLFWmousebuttonfun);
-//	glfwSetCursorPosCallback(window.glfwWindow, cast(GLFWcursorposfun)&_GLFWcursorposfun);
-//	//glfwSetCursorEnterCallback(window.glfwWindow, cast(GLFWcursorenterfunfun)&_GLFWcursorenterfunfun);
-//	glfwSetScrollCallback(window.glfwWindow, cast(GLFWscrollfun)&_GLFWscrollfun);
-//	glfwSetKeyCallback(window.glfwWindow, cast(GLFWkeyfun)&_GLFWkeyfun);
-//	glfwSetCharCallback(window.glfwWindow, cast(GLFWcharfun)&_GLFWcharfun);
-
-	glfwMakeContextCurrent(window.glfwWindow);
-}
-
-void destruct(ref Window window) nothrow @nogc {
-//	glfwSetWindowPosCallback(window.glfwWindow, null);
-//	glfwSetWindowSizeCallback(window.glfwWindow, null);
-//	glfwSetWindowCloseCallback(window.glfwWindow, null);
-//	glfwSetWindowRefreshCallback(window.glfwWindow, null);
-//	glfwSetWindowIconifyCallback(window.glfwWindow, null);
-//	glfwSetMouseButtonCallback(window.glfwWindow, null);
-//	glfwSetCursorPosCallback(window.glfwWindow, null);
-//	//glfwSetCursorEnterCallback(this._glfwWindow, null);
-//	glfwSetScrollCallback(window.glfwWindow, null);
-//	glfwSetKeyCallback(window.glfwWindow, null);
-//	glfwSetCharCallback(window.glfwWindow, null);
-	
-	glfwDestroyWindow(window.glfwWindow);
-
-	window = Window.init;
-}
-
-void makeAktiveRenderWindow(ref Window window) nothrow @nogc {
-	glfwMakeContextCurrent(window.glfwWindow);
-}
-
-void swapBuffers(ref Window window) nothrow @nogc {
-	glfwSwapBuffers(window.glfwWindow);
-}
-
-void pollEvents(ref Window window) nothrow @nogc {
-	glfwPollEvents();
-}
-
-@property void setTitle(ref Window window, string title) nothrow {
-	glfwSetWindowTitle(window.glfwWindow, title.toStringz());
-}
-
-KeyAction keyState(ref Window window, int key) pure @safe nothrow {
-	try {
-		return window.keyStates.get(key, KeyAction.Released);
-	}
-	catch(Exception) {
-		return KeyAction.Released;
-	}
-}
-
-ButtonAction buttonState(ref Window window, int button) pure @safe nothrow {
-	try {
-		return window.buttonStates.get(button, ButtonAction.Released);
-	}
-	catch(Exception) {
-		return ButtonAction.Released;
-	}
-}
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct Viewport {
-}
-
-void construct(out Viewport viewport) pure @safe nothrow @nogc {
-}
-
-void destruct(ref Viewport viewport) pure @safe nothrow @nogc {
-	viewport = Viewport.init;
-}
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct Scene {
-	SOAMesh mesh;
-}
-
-void construct(out Scene scene) pure @safe nothrow @nogc {
-}
-
-void destruct(ref Scene scene) pure @safe nothrow @nogc {
-	scene = Scene.init;
-}
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct Camera {
-}
-
-void construct(out Camera camera) pure @safe nothrow @nogc {
-}
-
-void destruct(ref Camera camera) pure @safe nothrow @nogc {
-	camera = Camera.init;
-}
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct RenderTarget {
-	uint width;
-	uint height;
-	GLuint textureTarget;
-}
-
-void construct(out RenderTarget renderTarget, uint width, uint height) nothrow {
-	renderTarget.width = width;
-	renderTarget.height = height;
-	glCheck!glGenTextures(1, &renderTarget.textureTarget);
-	glCheck!glBindTexture(GL_TEXTURE_2D, renderTarget.textureTarget);
-	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, width, height);
-	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
-	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-void destruct(ref RenderTarget renderTarget) nothrow {
-	glCheck!glDeleteTextures(1, &renderTarget.textureTarget);
-	renderTarget = RenderTarget.init;
-}
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct GBuffer {
-	uint width;
-	uint height;
-	GLuint textureDepth;
-	GLuint textureNormal;
-	GLuint textureColor;
-	GLuint textureDepthStencil;
-	GLuint fbo;
-}
-
-void construct(out GBuffer gBuffer, uint width, uint height) nothrow {
-	gBuffer.width = width;
-	gBuffer.width = height;
-
-	glCheck!glGenTextures(1, &gBuffer.textureDepth);		
-	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureDepth);
-	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-//	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
-	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, width, height);
-	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, null);	
-	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
-	
-	glCheck!glGenTextures(1, &gBuffer.textureNormal);
-	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureNormal);
-	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	
-//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB10_A2, width, height);
-	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
-	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
-	
-	glCheck!glGenTextures(1, &gBuffer.textureColor);
-	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureColor);
-	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
-	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
-	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
-	
-	glCheck!glGenTextures(1, &gBuffer.textureDepthStencil);
-	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureDepthStencil);
-	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, width, height);
-	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, null);	
-	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
-
-	glCheck!glGenFramebuffers(1, &gBuffer.fbo);
-	glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gBuffer.fbo);
-
-	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, gBuffer.textureDepth, 0);
-	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 1, GL_TEXTURE_2D, gBuffer.textureNormal, 0);
-	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 2, GL_TEXTURE_2D, gBuffer.textureColor, 0);
-	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, gBuffer.textureDepthStencil, 0);
-
-	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-}
-
-void destruct(ref GBuffer gBuffer) nothrow {
-	glCheck!glDeleteFramebuffers(1, &gBuffer.fbo);
-	glCheck!glDeleteTextures(1, &gBuffer.textureDepthStencil);
-	glCheck!glDeleteTextures(1, &gBuffer.textureColor);
-	glCheck!glDeleteTextures(1, &gBuffer.textureNormal);
-	glCheck!glDeleteTextures(1, &gBuffer.textureDepth);
-	gBuffer = GBuffer.init;
-}
-
-
-struct Pipeline {
-	GLuint pipeline;
-	GLuint vertexShaderGeometryPass;
-	GLuint fragmentShaderGeometryPass;
-}
-
-void construct(out Pipeline pipeline) nothrow {
-	glGenProgramPipelines(1, &pipeline.pipeline); 
-}
-
-void destruct(ref Pipeline pipeline) nothrow {
-	glDeleteProgramPipelines(1, &pipeline.pipeline);
-	pipeline = Pipeline.init;
-}
-
-
-struct OpenGlTiledDeferredRenderer {
-	GBuffer gBuffer;
-	Pipeline pipeline;
-}
-
-void construct(out OpenGlTiledDeferredRenderer deferredRenderer, uint width, uint height) nothrow {
-	deferredRenderer.gBuffer.construct(width, height);
-}
-
-void destruct(ref OpenGlTiledDeferredRenderer deferredRenderer) nothrow {
-	deferredRenderer.gBuffer.destruct();
-	deferredRenderer = OpenGlTiledDeferredRenderer.init;
-}
-
-// draw the scene supersampled with renderer's with+height onto renderTarget at position+size of viewport
-void renderOneFrame(ref OpenGlTiledDeferredRenderer renderer, ref Scene scene, ref Camera camera, ref RenderTarget renderTarget, ref Viewport viewport) nothrow {
-	// 1. Render the (opaque) geometry into the G-Buffers.	
-	// 2. Construct a screen space grid, covering the frame buffer, with some fixed tile
-	//    size, t = (x, y), e.g. 32 × 32 pixels.	
-	// 3. For each light: find the screen space extents of the light volume and append the
-	//    light ID to each affected grid cell.	
-	// 4. For each fragment in the frame buffer, with location f = (x, y).
-	//    (a) sample the G-Buffers at f.
-	//    (b) accumulate light contributions from all lights in tile at ⌊f /t⌋
-	//    (c) output total light contributions to frame buffer at f
-
-
-	with(renderer.gBuffer) glCheck!glViewport(0, 0, width, height);
-
-	//enable depth mask _before_ glClear ing the depth buffer!
-	glCheck!glDepthMask(GL_TRUE); scope(exit) glCheck!glDepthMask(GL_FALSE);
-	glCheck!glEnable(GL_DEPTH_TEST); scope(exit) glCheck!glDisable(GL_DEPTH_TEST);
-	glCheck!glDepthFunc(GL_LEQUAL);
-
-	//bind gBuffer
-	glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderer.gBuffer.fbo); scope(exit) glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
-	glCheck!glDrawBuffer(GL_COLOR_ATTACHMENT0 + 0);
-	glCheck!glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-	GLenum[] drawBuffers = [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2];
-	glCheck!glDrawBuffers(drawBuffers.length, drawBuffers.ptr);
-	glCheck!glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-
-	//bind pipeline
-	glCheck!glBindProgramPipeline(renderer.pipeline.pipeline); scope(exit) glCheck!glBindProgramPipeline(0);
-
-	{// Draw Geometry
-		scope(exit) glCheck!glBindVertexArray(0);
-		scope(exit) glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // TODO: GL_ELEMENT_ARRAY_BUFFER should be vao state, but bugs might make this necessary
-
-		for(size_t meshIdx = 0; meshIdx < scene.mesh.cnt; ++meshIdx) {
-			glCheck!glBindVertexArray(scene.mesh.vao[meshIdx]); 
-
-			glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, scene.mesh.vboIndices[meshIdx]); // TODO: GL_ELEMENT_ARRAY_BUFFER should be vao state, but bugs might make this necessary
-
-			glCheck!glDrawElements(GL_TRIANGLES, scene.mesh.cntIndices[meshIdx], GL_UNSIGNED_SHORT, null);
-		}
-	}
-}
-
-
-
-
-//======================================================================================================================
-// 
-//======================================================================================================================
-struct SOAMesh {
-	SoA!GLuint vao;
-	SoA!GLuint vboVertices;
-	SoA!GLuint vboNormals;
-	SoA!GLuint vboTexcoords;
-	SoA!GLuint vboColors;
-	SoA!GLuint vboIndices;
-	SoA!GLuint cntIndices;
-	size_t cnt;
-}
-
-void loadModel(ref SOAMesh mesh, string filePath) {
-	import std.traits;
-	auto scene = aiImportFile(filePath.toStringz(),	aiProcess_Triangulate); scope(exit) aiReleaseImport(scene);
-
-	for(uint m = 0; m < scene.mNumMeshes; ++m) {	
-		const(aiMesh*) meshData = scene.mMeshes[m];
-		assert(meshData !is null);
-		
-		//-----------------------------
-		// create mesh
-		auto meshIdx = mesh.cnt;
-		++mesh.cnt;
-		mesh.vao.length = mesh.cnt;
-		mesh.vboVertices.length = mesh.cnt;
-		mesh.vboNormals.length = mesh.cnt;
-		mesh.vboTexcoords.length = mesh.cnt;
-		mesh.vboIndices.length = mesh.cnt;
-		mesh.cntIndices.length = mesh.cnt;
-
-		//-----------------------------
-		// upload data
-		glCheck!glGenVertexArrays(1, &mesh.vao[meshIdx]);
-		glCheck!glBindVertexArray(mesh.vao[meshIdx]); scope(exit) glCheck!glBindVertexArray(0);
-
-		alias Vertex = float[3];
-		alias Normal = float[3];
-		alias TexCoord = float[2];
-		alias Color = float[4];
-		alias Index = uint[1];
-
-		size_t cntIndices = 0;
-		foreach(f; 0..meshData.mNumFaces) {
-			cntIndices += meshData.mFaces[f].mNumIndices;				
-		}
-
-		{// upload vertex data
-			Vertex[] vertexData;
-			vertexData.length = meshData.mNumVertices;
-			foreach(v; 0..meshData.mNumVertices) {
-				vertexData[v] = [meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z];
-			}
-			glCheck!glGenBuffers(1, &mesh.vboVertices[meshIdx]);
-			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboVertices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
-			GLuint attribIndex = 0;
-			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Vertex.sizeof * vertexData.length) , vertexData.ptr, GL_STATIC_DRAW);		
-			glCheck!glEnableVertexAttribArray(attribIndex);
-			glCheck!glVertexAttribPointer(attribIndex, Vertex.sizeof / ForeachType!Vertex.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
-		}
-
-		{// upload normal data
-			Normal[] normalData;
-			normalData.length = meshData.mNumVertices;
-			foreach(v; 0..meshData.mNumVertices) {
-				normalData[v] = [meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z];
-			}
-			glCheck!glGenBuffers(1, &mesh.vboNormals[meshIdx]);
-			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboNormals[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
-			GLuint attribIndex = 1;
-			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Normal.sizeof * normalData.length) , normalData.ptr, GL_STATIC_DRAW);		
-			glCheck!glEnableVertexAttribArray(attribIndex);
-			glCheck!glVertexAttribPointer(attribIndex, Normal.sizeof / ForeachType!Normal.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
-		}
-
-		if(meshData.mTextureCoords[0] !is null) {// upload texture data
-			TexCoord[] textureData;
-			textureData.length = meshData.mNumVertices;
-			foreach(v; 0..meshData.mNumVertices) {
-				textureData[v] = [meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y];
-			}
-			glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
-			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
-			GLuint attribIndex = 2;
-			glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(TexCoord.sizeof * textureData.length) , textureData.ptr, GL_STATIC_DRAW);		
-			glEnableVertexAttribArray(attribIndex);
-			glVertexAttribPointer(attribIndex, TexCoord.sizeof / ForeachType!TexCoord.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
-		}
-
-		if(meshData.mColors[0] !is null) {// upload color data
-			Color[] colorData;
-			colorData.length = meshData.mNumVertices;
-			foreach(v; 0..meshData.mNumVertices) {
-				colorData[v] = [meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a];
-			}
-			glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
-			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
-			GLuint attribIndex = 2;
-			glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Color.sizeof * colorData.length) , colorData.ptr, GL_STATIC_DRAW);		
-			glEnableVertexAttribArray(attribIndex);
-			glVertexAttribPointer(attribIndex, Color.sizeof / ForeachType!Color.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
-		}
-
-		{// upload index data
-			Index[] indexData;
-			indexData.length = cntIndices;
-			size_t curIndexDataIdx = 0;
-			foreach(f; 0..meshData.mNumFaces) {
-				assert(meshData.mFaces !is null);
-				foreach(i; 0..meshData.mFaces[f].mNumIndices) {
-					assert(meshData.mFaces[f].mIndices !is null);
-					indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];		
-				}
-			}
-			glCheck!glGenBuffers(1, &mesh.vboIndices[meshIdx]);
-			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboIndices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
-			GLuint attribIndex = 3;
-			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Index.sizeof * indexData.length) , indexData.ptr, GL_STATIC_DRAW);		
-			glCheck!glEnableVertexAttribArray(attribIndex);
-			glCheck!glVertexAttribPointer(attribIndex, Index.sizeof / ForeachType!Index.sizeof, GL_UNSIGNED_INT, GL_FALSE, 0, cast(void*)0);
-		}
-	}
-}
 
 //======================================================================================================================
 // 
@@ -697,6 +38,7 @@ void main() {
 	Camera camera;
 	RenderTarget renderTarget;
 	OpenGlTiledDeferredRenderer renderer;
+	bool keepRunning = true;
 
 	DerelictGL3.load();
 	DerelictGLFW3.load();
@@ -732,7 +74,54 @@ void main() {
 	TwWindowSize(window.width, window.height);
 	auto tweakBar = TwNewBar("TweakBar");
 
-	while(true) {
+
+	window.onKey = (Window* pWindow, Key key, ScanCode scanCode, KeyAction action, KeyMod keyMod) {
+		if(window is window && action == KeyAction.Pressed) {
+			if(key == Key.Escape) {
+				keepRunning = false;
+			}
+		}
+	};
+
+	window.onClose = (Window* pWindow) {
+		keepRunning = false;
+	};
+
+	window.onSize = (Window* pWindow, int width, int height) {
+		TwWindowSize(width, height);		
+	};
+
+	window.onPosition = (Window* pWindow, int x, int y) {		
+	};
+
+	window.onButton = (Window* pWindow , int button, ButtonAction action) {
+		TwMouseAction twaction = action == ButtonAction.Pressed ? TW_MOUSE_PRESSED : TW_MOUSE_RELEASED;
+		TwMouseButtonID twbutton;
+		
+		switch(button) {
+			default:
+			case GLFW_MOUSE_BUTTON_LEFT: twbutton = TW_MOUSE_LEFT; break;
+			case GLFW_MOUSE_BUTTON_RIGHT: twbutton = TW_MOUSE_RIGHT; break;
+			case GLFW_MOUSE_BUTTON_MIDDLE: twbutton = TW_MOUSE_MIDDLE; break;			
+		}
+		
+		TwMouseButton(twaction, twbutton);		
+	};
+
+	window.onCursorPos = (Window* pWindow, double x, double y) {
+		TwMouseMotion(cast(int)x, window.height - cast(int)y);
+	};
+
+
+
+
+
+
+
+
+
+
+	while(keepRunning) {
 		window.pollEvents();
 
 		window.makeAktiveRenderWindow();

+ 0 - 76
source/three/anttweakbar/anttweakbar.d

@@ -1,76 +0,0 @@
-module three.anttweakbar.anttweakbar;
-
-import derelict.anttweakbar.anttweakbar;
-
-import std.string;
-import std.stdio;
-
-import three.primitives;
-
-
-template toAntTweakBarType(T) {
-	static if(is(T == bool)) {
-		alias toAntTweakBarType = TW_TYPE_BOOLCPP;
-	}
-	else static if(is(T == byte)) {
-		alias toAntTweakBarType = TW_TYPE_INT8;
-	}
-	else static if(is(T == short)) {
-		alias toAntTweakBarType = TW_TYPE_INT16;
-	}
-	else static if(is(T == int)) {
-		alias toAntTweakBarType = TW_TYPE_INT32;
-	}
-	else static if(is(T == ubyte)) {
-		alias toAntTweakBarType = TW_TYPE_UINT8;
-	}
-	else static if(is(T == ushort)) {
-		alias toAntTweakBarType = TW_TYPE_UINT16;
-	}
-	else static if(is(T == uint)) {
-		alias toAntTweakBarType = TW_TYPE_UINT32;
-	}
-	else static if(is(T == float)) {
-		alias toAntTweakBarType = TW_TYPE_FLOAT;
-	}
-	else static if(is(T == double)) {
-		alias toAntTweakBarType = TW_TYPE_DOUBLE;
-	}
-	else static if(is(T == Vector3f)) {
-		alias toAntTweakBarType = TW_TYPE_DIR3D;
-	}
-	else static if(is(T == Quaternionf)) {
-		alias toAntTweakBarType = TW_TYPE_QUAT4F;
-	}
-	else static assert(false, "no type convertion possible");
-}
-
-
-final class TweakBar {
-private:
-	TwBar* _handle;
-	
-public:	   
-	///
-	this(string name) {
-		this._handle = TwNewBar(name.toStringz());
-		writeln("TweakBar created: ", this._handle);
-	}
-	
-	///
-	~this() {
-		TwDeleteBar(this._handle);
-		writeln("TweakBar destroyed: ", this._handle);
-	}
-
-public:
-	void addVarRW(T)(string name, string def, ref T t) {
-		TwAddVarRW(this._handle, name.toStringz(), toAntTweakBarType!T, &t, def.toStringz());
-	}
-		
-public:	  
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._handle != null);
-	}
-}

+ 0 - 3
source/three/anttweakbar/package.d

@@ -1,3 +0,0 @@
-module three.anttweakbar;
-
-public import three.anttweakbar.anttweakbar;

+ 0 - 79
source/three/assimp/package.d

@@ -1,79 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-
-
-
-module three.assimp;
-
-import std.traits;
-
-
-version(none){
-
-Model loadModel(string filePath, Vec3f position = Vec3f(0,0,0), Vec3f scale = Vec3f(1,1,1), Quatf orientation = Quatf(0,0,0,1)) {
-	if(!exists(filePath)) throw new Exception("File does not exist");
-	try{			
-		"loading model: ".writeln(filePath);
-		auto scene = aiImportFile(filePath.toStringz(),	0
-		                          //| aiPostProcessSteps.CalcTangentSpace
-		                          //| aiPostProcessSteps.Triangulate
-		                          //| aiPostProcessSteps.JoinIdenticalVertices
-		                          //| aiPostProcessSteps.GenNormals
-		                          //| aiPostProcessSteps.FlipWindingOrder
-		                          //| aiPostProcessSteps.SortByPType
-		                          );
-		
-		Mesh[] meshes;	
-		
-		for(uint k = 0; k < scene.mNumMeshes; ++k) {  
-			
-			"mesh".writeln();
-			const(aiMesh*) mesh = scene.mMeshes[k];
-			assert(mesh !is null);
-			float[] vertexData;
-			
-			for (uint t = 0; t < mesh.mNumFaces; ++t) {	 
-				//"face".writeln();
-				const(aiFace*) face = &mesh.mFaces[t];
-				assert(face !is null);
-				for(uint v = 0; v < 3; ++v) {  
-					//"a".writeln();
-					aiVector3D p, n, uv;  
-					assert(face.mNumIndices > v);
-					uint vertex = face.mIndices[v];
-					assert(mesh.mNumVertices > vertex);
-					p = mesh.mVertices[vertex];
-					n = mesh.mNormals[vertex];	              
-					
-					// check if the mesh has texture coordinates
-					if(mesh.mTextureCoords[0] !is null) {
-						uv = mesh.mTextureCoords[0][vertex];
-					}
-					
-					//TODO: speed this up!
-					vertexData ~= [p.x, p.y, p.z, n.x, n.y, n.z, uv.x, uv.y, 1.0f, 1.0f, 1.0f];
-				}
-			}
-			
-			"genvdata".writeln();
-			//alias VertexData!(VertexBufferObject!(BufferTarget.Array, VTX_POSITION, VTX_NORMAL, VTX_TEXCOORD, VTX_COLOR)) AssimpVertexData;
-			//meshes ~= new VertexMesh!(AssimpVertexData)(vertexData, mesh.mNumFaces);
-		}
-		
-		
-		"release".writeln();
-		aiReleaseImport(scene);
-		"loaded".writeln();
-		return new Model(position, scale, orientation, meshes);	 
-	}catch(Exception e)
-	{
-		assert(0);
-	}
-}
-}

+ 13 - 0
source/three/camera.d

@@ -0,0 +1,13 @@
+module three.camera;
+
+import three.common;
+
+struct Camera {
+}
+
+void construct(out Camera camera) pure @safe nothrow @nogc {
+}
+
+void destruct(ref Camera camera) pure @safe nothrow @nogc {
+	camera = Camera.init;
+}

+ 62 - 0
source/three/common.d

@@ -0,0 +1,62 @@
+module three.common;
+
+public import derelict.opengl3.gl3;
+public import derelict.glfw3.glfw3;
+public import derelict.anttweakbar.anttweakbar;
+public import derelict.freeimage.freeimage;	
+public import derelict.freetype.ft;
+public import derelict.assimp3.assimp;
+
+alias SoA(T) = T[];
+
+
+
+import std.traits : ReturnType;
+
+ReturnType!func glCheck(alias func, string file = __FILE__, size_t line = __LINE__, string mod = __MODULE__, string funcd = __FUNCTION__, string pretty = __PRETTY_FUNCTION__, Args...)(Args args) nothrow {
+	import std.stdio;
+	import std.stdio : stderr;
+	import std.array : join;
+	import std.range : repeat;
+	import std.string : format;
+	try{
+		debug scope(exit) {
+			GLenum err = glGetError();
+			if(err != GL_NO_ERROR) {
+				stderr.writeln("\n===============================");
+				stderr.writeln("File: ", file, "\nLine: ", line, "\nModule: ",mod, "\nFunction: ",funcd, "\n",pretty);
+				stderr.writeln("-------------------------------");
+				stderr.writefln(`OpenGL function "%s(%s)" failed: "%s."`, func.stringof, format("%s".repeat(Args.length).join(", "), args), glErrorString(err));
+				stderr.writeln("=============================== \n");
+				assert(false);
+			}
+		}
+	}
+	catch(Exception e){
+	}
+	
+	debug if(func is null) {
+		try{
+			stderr.writefln("%s is null! OpenGL loaded? Required OpenGL version not supported?".format(func.stringof));
+		}
+		catch(Exception e){
+			assert(false);
+		}
+		assert(false);
+	}	
+	return func(args);
+}
+
+string glErrorString(GLenum error) pure @safe nothrow @nogc {
+	final switch(error) {
+		case GL_NO_ERROR: return "no error";
+		case GL_INVALID_ENUM: return "invalid enum";
+		case GL_INVALID_VALUE: return "invalid value";
+		case GL_INVALID_OPERATION: return "invalid operation";
+			//case GL_STACK_OVERFLOW: return "stack overflow";
+			//case GL_STACK_UNDERFLOW: return "stack underflow";
+		case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffer operation";
+		case GL_OUT_OF_MEMORY: return "out of memory";
+	}
+	assert(false, "invalid enum");
+}

+ 0 - 9
source/three/gfx/material.d

@@ -1,9 +0,0 @@
-module three.gfx.material;
-
-//~ struct Material {
-	//~ BaseColor,
-	//~ float Metallic,
-	//~ float roughness,
-	//~ emissive, //(glow)
-	//~ normals
-//~ }

+ 0 - 1
source/three/gfx/package.d

@@ -1 +0,0 @@
-module three.gfx;

+ 0 - 0
source/three/gfx/pixel.d


+ 0 - 216
source/three/gfx/screen.d

@@ -1,216 +0,0 @@
-module three.gfx.scene;
-
-/+++
-
-struct PositionGraph {
-	struct InternalId {
-		uint id;
-
-		this(size_t depth, size_t position) {
-			id = (depth & 0x000000ff) | (position << 8);
-		}
-
-		size_t depth() {
-			return id & 0x000000ff;
-		}
-
-		size_t position() {
-			return (id & 0xffffff00) >>> 8;
-		}
-	}
-
-	enum initialDepth = 5;
-
-	InternalId[Entity] _internalMapping; //fast entity -> component lookup
-	SoAEntity[] _entity = new SoAEntity[initialDepth]; //fast component -> entity lookup
-	SoAVec3[] _position = new SoAVec3[initialDepth];
-
-	void createRootNode(Entity entity, Position position) {
-		_appendNode(0, entity, position);
-	}
-
-	void createChildNode(Entity parent, Entity entity, Position position) {
-		auto p = parent in _internalMapping;
-		if(p is null) {
-			//TODO: if not in there?
-		}
-		auto depth = p.depth + 1;
-		// increase depth array if not large enouth
-		if(_entity.length < depth) {
-			_entity.length = depth;
-		}
-		// assign values
-		append(depth, entity, position);
-	}
-
-private:
-	void _appendNode(size_t depth, Entity entity, Position position) {
-		_entity[depth].append(entity);
-		_position[depth].x.append(position.x);
-		_position[depth].y.append(position.y);
-		_position[depth].z.append(position.z);
-		_internalMapping[entity] = InternalId(depth, _entity[depth].length];
-	}
-}
-
-
-
-
-struct SoAEntity() {
-	Entity[] entity;
-}
-
-struct SoAVec3() {
-	float[] x;
-	float[] y;
-	float[] z;
-}
-
-struct SoAQuat() {
-	float[] x;
-	float[] y;
-	float[] z;
-	float[] w;
-}
-
-struct LocalTransformCM {
-private:
-	size_t _length = 0;
-	size_t _capacity = 0;
-	ubyte* _data;
-
-	mixin Vec3 _position;
-	mixin Quat _orientation;
-	mixin Vec3 _scale;
-	//~ mixin Vec3 _velocity;
-	//~ mixin Vec3 _acceleration;
-
-
-}
-
-
-
-class DebugNameCM {
-	void setDebugName(Entity e, string name);
-	string debugName(Entity e);
-}
-
-
-
-void vector(string op)(ref Vectors r, Vectors a, Vectors b) {
-	mixin("r.x[] = a.x[]" ~ op ~ "b.x[];");
-	mixin("r.y[] = a.y[]" ~ op ~ "b.y[];");
-	mixin("r.z[] = a.z[]" ~ op ~ "b.z[];");
-}
-
-void quat_mul(ref Quaternions r, Quaternions a, Quaternions b) {
-	r.x[] = a.w[] * b.x[] + a.x[] * b.w[] + b.y[] * b.z[] - a.z[] * b.y[];
-	r.y[] = a.w[] * b.y[] - a.x[] * b.z[] + a.y[] * b.w[] + a.z[] * b.x[];
-	r.z[] = a.w[] * b.z[] + a.x[] * b.y[] - a.y[] * b.x[] + a.z[] * b.w[];
-	r.w[] = a.w[] * b.w[] - a.x[] * b.x[] - a.y[] * b.y[] - a.z[] * b.z[];
-}
-
-struct Positions {
-	float[] x;
-	float[] z;
-	float[] x;
-}
-
-struct Orientations {
-	float[] x;
-	float[] z;
-	float[] x;
-	float[] w;
-}
-
-struct Scales {
-	float[] x;
-	float[] z;
-	float[] x;
-}
-
-struct Position {
-	float x;
-	float z;
-	float x;
-}
-
-struct Orientation {
-	float x;
-	float z;
-	float x;
-	float w;
-}
-
-struct Scale {
-	float x;
-	float z;
-	float x;
-}
-
-struct Scene {
-	Entity _entities;
-	Positions _positions;
-	Orientations _orientations;
-	Scales _scales;
-	int[] _parents;
-	
-	/// keep them sorted by tree depth, so we iterate the tree breath first when iterating the array
-	void insert(Entity entity, int parent, Position position, Orientation orientation, Scale scale) {
-		auto idx = parents.countUntil!(a=>a>b)(parent);
-		if(idx == -1) { // insert at end
-			_entities.append(entity);
-			
-			_parents.append(parent);
-			
-			_positions.x.append(position.x);
-			_positions.y.append(position.y);
-			_positions.z.append(position.z);
-			
-			_orientations.x.append(orientation.x);
-			_orientations.y.append(orientation.y);
-			_orientations.z.append(orientation.z);
-			_orientations.w.append(orientation.w);
-			
-			_scales.x.append(scale.x);
-			_scales.y.append(scale.y);
-			_scales.z.append(scale.z);
-		}
-		else { // insert at idx and move all right of idx
-			_entities.insertInPlace(idx, entity);
-			
-			_parents.insertInPlace(idx, parent);
-			
-			_positions.x.insertInPlace(idx, position.x);
-			_positions.y.insertInPlace(idx, position.y);
-			_positions.z.insertInPlace(idx, position.z);
-			
-			_orientations.x.insertInPlace(idx, orientation.x);
-			_orientations.y.insertInPlace(idx, orientation.y);
-			_orientations.z.insertInPlace(idx, orientation.z);
-			_orientations.w.insertInPlace(idx, orientation.w);
-			
-			_scales.x.insertInPlace(idx, scale.x);
-			_scales.y.insertInPlace(idx, scale.y);
-			_scales.z.insertInPlace(idx, scale.z);
-		}
-	}
-}
-
-// 4
-// 2 3 5 6
-//    ^x
-//
-
-// 1
-// 2 3 5 6
-//^x
-//
-
-// 9
-// 2 3 5 6
-//         ^x
-//
-
-
-+++/

+ 0 - 121
source/three/gl/framebuffer.d

@@ -1,121 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.framebuffer;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-import std.stdio;
-
-
-//==============================================================================
-///
-enum FramebufferTarget : GLenum {
-	Write = GL_DRAW_FRAMEBUFFER,
-	Read = GL_READ_FRAMEBUFFER
-}
-
-
-//==============================================================================
-///
-enum FramebufferStatus : GLenum {
-	Complete = GL_FRAMEBUFFER_COMPLETE,
-	Error = 0,
-	Undefines = GL_FRAMEBUFFER_UNDEFINED,
-	IncompleteAttachment = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
-	IncompleteMissingAttachment = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
-	IncompleteDrawBuffer = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER,
-	IncompleteReadBuffer = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER,
-	Unsupported = GL_FRAMEBUFFER_UNSUPPORTED,
-	IncompleteMultisample = GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,        
-	IncompleteLayerTargets = GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
-}
-
-
-//==============================================================================
-///
-enum FramebufferAttachment {
-	Color = GL_COLOR_ATTACHMENT0, 
-	Depth = GL_DEPTH_ATTACHMENT, 
-	Stencil = GL_STENCIL_ATTACHMENT,
-	DepthStencil = GL_DEPTH_STENCIL_ATTACHMENT
-}
-
-
-//==============================================================================
-///
-final class Framebuffer {
-private:
-	GLuint _id;
-
-public:	   
-	///
-	this() {
-		check!glGenFramebuffers(1, &this._id); 
-		writeln("Framebuffer created: ", this._id);
-	}
-
-	///
-	~this() {
-		check!glDeleteFramebuffers(1, &this._id);
-		writeln("Framebuffer destroyed: ", this._id);
-	}
-	
-public:	   
-	///
-	void bind(FramebufferTarget target) { 
-		assert(this.isValid);
-		check!glBindFramebuffer(target, this._id);
-	}    
-
-	///
-	static void unbind(FramebufferTarget target) { 
-		check!glBindFramebuffer(target, 0);
-	}
-		
-	
-	//~ version(OpenGL4) {
-		//~ void defaultWidth(Target target, uint width) { check!glFramebufferParameteri(target, GL_FRAMEBUFFER_DEFAULT_WIDTH, width); }
-		//~ uint defaultWidth(Target target) { GLint width; check!glGetFramebufferParameteriv(target, GL_FRAMEBUFFER_DEFAULT_WIDTH, &width); }
-		
-		//~ void defaultHeight(Target target, uint height) { check!glFramebufferParameteri(target, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height); }
-		//~ uint defaultWidth(Target target) { GLint height; check!glGetFramebufferParameteriv(target, GL_FRAMEBUFFER_DEFAULT_HEIGHT, &height); }
-		
-		//~ void defaultLayers(Target target, uint layers) { check!glFramebufferParameteri(target, GL_FRAMEBUFFER_DEFAULT_LAYERS, layers); }
-		//~ uint defaultWidth(Target target) { GLint layers; check!glGetFramebufferParameteriv(target, GL_FRAMEBUFFER_DEFAULT_LAYERS, &layers); }
-		
-		//~ void defaultSamles(Target target, uint samples) { check!glFramebufferParameteri(target, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples); }
-		//~ uint defaultWidth(Target target) { GLint samples; check!glGetFramebufferParameteriv(target, GL_FRAMEBUFFER_DEFAULT_SAMPLES, &samples); }
-		
-		//~ void defaultFixedSampleLocations(Target target, uint fixedSampleLocations) { check!glFramebufferParameteri(target, GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS, fixedSampleLocations); }
-		//~ uint defaultFixedSampleLocations(Target target) { GLint fixedSampleLocations; check!glGetFramebufferParameteriv(target, GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS, &fixedSampleLocations); }
-	//~ }
-	
-	//~ void attach(Target target, Attachment attachment, Texture texture, uint location) {
-		//~ debug{assert(this.db_isBound(target), "framebuffer not bound");}
-		//~ switch(attachment) {
-			//~ case Attachment.Color:
-				//~ check!glFramebufferTexture2D(target, attachment + location, GL_TEXTURE_2D, texture.id, 0);
-				//~ break;
-			//~ default:
-				//~ check!glFramebufferTexture2D(target, attachment, GL_TEXTURE_2D, texture.id, 0);
-		//~ }
-	//~ }
-	
-public:		
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._id > 0);
-	}
-		
-	///
-	static FramebufferStatus status(FramebufferTarget target) {
-		return cast(FramebufferStatus) check!glCheckFramebufferStatus(target);
-	}    
-}

+ 0 - 17
source/three/gl/package.d

@@ -1,17 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl;
-				   
-public import three.gl.framebuffer;
-public import three.gl.renderbuffer;
-public import three.gl.shader;
-public import three.gl.texture;
-public import three.gl.util;
-public import three.gl.vao;	  
-public import three.gl.vbo;

+ 0 - 52
source/three/gl/renderbuffer.d

@@ -1,52 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.renderbuffer;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-import std.stdio;
-
-//==============================================================================
-///
-final class Renderbuffer {
-private:
-	GLuint _id;
-
-public:	   
-	///
-	this() {
-		check!glGenRenderbuffers(1, &this._id);
-		writeln("Renderbuffer created: ", this._id);
-	}
-
-	///
-	~this() {
-		check!glDeleteRenderbuffers(1, &this._id); 
-		writeln("Renderbuffer destroxed: ", this._id);
-	}
-	
-public:	  
-	///
-	void bind() { 
-		assert(this.isValid);
-		check!glBindRenderbuffer(GL_RENDERBUFFER, this._id);
-	}
-
-	///
-	static void unbind(){ 
-		check!glBindRenderbuffer(GL_RENDERBUFFER, 0);
-	}  
-	
-public:	  
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._id > 0);
-	}
-}

+ 0 - 169
source/three/gl/shader.d

@@ -1,169 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.shader;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-import std.string;
-import std.stdio;
-
-//==============================================================================
-///
-enum ShaderType {
-	Vertex      			= GL_VERTEX_SHADER,
-	Fragment    			= GL_FRAGMENT_SHADER,
-	Geometry    			= GL_GEOMETRY_SHADER,
-	TesselationControl 		= GL_TESS_CONTROL_SHADER, 
-	TesselationEvaluation 	= GL_TESS_EVALUATION_SHADER
-}
-
-private template shaderTypeBitIdentifier(ShaderType TYPE)
-{
-	static if(TYPE == ShaderType.Vertex) enum shaderTypeBitIdentifier = GL_VERTEX_SHADER_BIT;
-	else static if(TYPE == ShaderType.Fragment) enum shaderTypeBitIdentifier = GL_FRAGMENT_SHADER_BIT;
-	else static if(TYPE == ShaderType.Geometry) enum shaderTypeBitIdentifier = GL_GEOMETRY_SHADER_BIT;
-	else static if(TYPE == ShaderType.TesselationControl) enum shaderTypeBitIdentifier = GL_TESS_CONTROL_SHADER_BIT;
-	else static if(TYPE == ShaderType.TesselationEvaluation) enum shaderTypeBitIdentifier = GL_TESS_EVALUATION_SHADER_BIT;
-}
-
-//==============================================================================
-///
-final class Shader(ShaderType TYPE) {		
-private:
-	uint _id;
-	int[string] _uniformLocationCache;
-	alias type = TYPE;
-public:	   
-	///
-	this(string source) {
-		auto szSource = [source.toStringz()];
-		this._id = check!glCreateShaderProgramv(TYPE, 1, szSource.ptr);
-		writeln("Shader created: ", this._id);
-	}
-
-	///
-	~this() {
-		check!glDeleteProgram(this._id);
-		writeln("Shader deleted: ", this._id);
-	}
-
-public:	  
-	///
-	@property bool isValid() const {
-		return (this._id > 0 && this.isLinked);
-	}
-
-	///
-	@property bool isLinked() const {
-		GLint linked;
-		check!glGetProgramiv(this._id, GL_LINK_STATUS, &linked);
-		return linked != 0;
-	}
-	
-public:	  
-	///
-	int getUniformLocation(string name) {
-		int* px = (name in this._uniformLocationCache);
-		if(px !is null) return *px;
-		auto szName = name.toStringz();
-		assert(this._id > 0);
-		int x = check!glGetUniformLocation(this._id, &szName[0]);
-		assert(x != -1, "wrong uniform location : " ~ name);
-		//try{if(x == -1) "wrong uniform location : ".writeln(name);}catch(Exception e){}
-		
-		this._uniformLocationCache[name] = x;
-		//if(x == -1) throw new Exception("uniform location "~name~" not found");
-		return x;
-	}	
-
-	///
-	string infoLog() const {
-		int len;
-		check!glGetProgramiv(this._id, GL_INFO_LOG_LENGTH , &len);
-		if (len > 1) {
-			char[] msg = new char[len];
-			check!glGetProgramInfoLog(this._id, len, null, cast(char*) msg);
-			return cast(string)msg;
-		}
-		return "";
-	}
-}
-
-
-//==============================================================================
-///
-final class ShaderPipeline {
-private:
-	GLuint _id;
-	uint[ShaderType] _currentlyUsed;
-	
-public:	 
-	///
-	this() { 
-		glGenProgramPipelines(1, &this._id); 
-		writeln("ShaderPipeline created: ", this._id);
-	}
-
-	///
-	~this() { 
-		glDeleteProgramPipelines(1, &this._id);
-		writeln("ShaderPipeline deleted: ", this._id);
-	}
-	
-public:			
-	///
-	@property bool isValid() const {
-		return (this._id > 0 && this.isValidProgramPipeline);
-	}
-
-	///
-	@property bool isValidProgramPipeline() const { 
-		glValidateProgramPipeline(this._id); 
-		GLint status;
-		glGetProgramPipelineiv(this._id, GL_VALIDATE_STATUS, &status);
-		return status != 0;
-	}
-	
-public:    
-	/// 
-	void bind()  { 
-		assert(this.isValid);
-		glBindProgramPipeline(this._id); 
-	}
-
-	///
-	static void unbind()  { 
-		glBindProgramPipeline(0);
-	}
-
-	///
-	void activate(T)(T shaderProgram) { // TODO: add check if it is a shaderProgram
-		glActiveShaderProgram(this._id, shaderProgram._id);
-	}
-
-	///
-	void use(T)(T shaderProgram) { // TODO: add check if it is a shaderProgram
-		//check if shaderProgram is already in use by this pipeline
-		if(_currentlyUsed.get(T.type, 0) == shaderProgram._id) return;
-		glUseProgramStages(this._id, shaderTypeBitIdentifier!(shaderProgram.type), shaderProgram._id);
-	}
-
-	///
-	string infoLog() const {
-		int len;
-		glGetProgramiv(this._id, GL_INFO_LOG_LENGTH , &len);
-		if (len > 1) {
-			char[] msg = new char[len];
-			glGetProgramPipelineInfoLog(this._id, len, null, cast(char*) msg);
-			return cast(string)msg;
-		}
-		return "";
-	}
-}

+ 0 - 346
source/three/gl/texture.d

@@ -1,346 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.texture;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-import std.stdio;
-
-//==============================================================================
-enum TextureTarget : GLenum {		
-	Texture1D = GL_TEXTURE_1D, 
-	Texture2D = GL_TEXTURE_2D, 
-	Texture3D = GL_TEXTURE_3D, 
-	Texture1DArray = GL_TEXTURE_1D_ARRAY, 
-	Texture2DArray = GL_TEXTURE_2D_ARRAY, 
-	TextureRectangle = GL_TEXTURE_RECTANGLE, 
-	TextureCubeMap = GL_TEXTURE_CUBE_MAP, 
-	TextureCubeMapArray = GL_TEXTURE_CUBE_MAP_ARRAY, 
-	TextureBuffer = GL_TEXTURE_BUFFER, 
-	Texture2DMultisample = GL_TEXTURE_2D_MULTISAMPLE,
-	Texture2DMultisampleArray = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
-	
-	//~ CubeMapPositiveX = GL_TEXTURE_CUBE_MAP_POSITIVE_X, 
-	//~ CubeMapNegativeX = GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 
-	//~ CubeMapPositiveY = GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 
-	//~ CubeMapNegativeY = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 
-	//~ CubeMapPositiveZ = GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 
-	//~ CubeMapNegativeZ = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 
-}
-
-
-//==============================================================================
-static struct TextureUnit(size_t locationIdx, TextureTarget textureTarget) {
-    @disable this();
-    @disable this(this); 
-public:	
-	static void makeActive() {
-		check!glActiveTexture(GL_TEXTURE0 + locationIdx);
-	}
-
-	static void bindTexture(Texture texture) { 
-		glBindTexture(textureTarget, texture._id);
-	}
-    
-    static void unbindTexture() { 
-		glBindTexture(textureTarget, 0);
-	}
-	
-public:
-	version(OpenGL4) {
-        @property void depthStencilTextureMode(StencilTextureMode opt) {
-            glTexParameteri(textureTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, opt); 
-        }
-        
-        @property StencilTextureMode depthStencilTextureMode(Target target) {             
-            StencilTextureMode opt;
-            glGetTexParameteri(textureTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, &opt); 
-            return opt;
-        }
-    }
-    
-    @property void baseLevel(int opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, opt); 
-    }
-	
-    @property int baseLevel() {
-        int opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_BASE_LEVEL, &opt); 
-        return opt;
-    }
-     
-    @property void borderColor(Color color) {
-        glTexParameterfv(textureTarget, GL_TEXTURE_BORDER_COLOR, color.data.ptr);
-    }
-	
-    @property Color borderColor() {
-        Color color;
-        glGetTexParameterfv(textureTarget, GL_TEXTURE_BORDER_COLOR, color.data.ptr);
-        return color;
-    }
-    
-    @property void compareFunction(CompareFunction opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_COMPARE_FUNC, opt); 
-    }
-	
-    @property CompareFunction compareFunction() {
-        CompareFunction opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_COMPARE_FUNC, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void compareMode(CompareMode opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_COMPARE_MODE, opt); 
-    }
-	
-    @property int compareMode() {
-        CompareMode opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_COMPARE_MODE, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void lodBias(float opt) {
-        glTexParameterf(textureTarget, GL_TEXTURE_LOD_BIAS, opt);    
-    }
-	
-    @property float lodBias() {
-        float opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_LOD_BIAS, cast(int*)&opt); 
-        return opt;
-    }
-
-    @property void minFilter(MinFilter opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, opt);    
-    }
-	
-    @property MinFilter minFilter() {
-        MinFilter opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_MIN_FILTER, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void magFilter(MagFilter opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, opt);    
-    }
-	
-    @property MagFilter magFilter() {
-        MagFilter opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_MAG_FILTER, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void minLod(int opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_MIN_LOD, opt);    
-    }
-	
-    @property int minLod() {
-        int opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_MIN_LOD, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void maxLod(int opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_MAX_LOD, opt);    
-    }
-	
-    @property int maxLod() {
-        int opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_MAX_LOD, cast(int*)&opt); 
-        return opt;
-    }
-    
-    @property void maxLevel(int opt) {
-        glTexParameteri(textureTarget, GL_TEXTURE_MAX_LEVEL, opt);    
-    }
-	
-    @property int maxLevel() {
-        int opt;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_MAX_LEVEL, cast(int*)&opt); 
-        return opt;
-    }
-    
-    void setSwizzle(Swizzle r, Swizzle g, Swizzle b, Swizzle a) {
-        glTexParameteri(textureTarget, GL_TEXTURE_SWIZZLE_R, r); 
-        glTexParameteri(textureTarget, GL_TEXTURE_SWIZZLE_G, g); 
-        glTexParameteri(textureTarget, GL_TEXTURE_SWIZZLE_B, b); 
-        glTexParameteri(textureTarget, GL_TEXTURE_SWIZZLE_A, a);    
-    }
-	
-    void getSwizzle(out Swizzle r, out Swizzle g, out Swizzle b, out Swizzle a) {
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_SWIZZLE_R, cast(int*)&r);
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_SWIZZLE_G, cast(int*)&g);
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_SWIZZLE_B, cast(int*)&b);
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_SWIZZLE_A, cast(int*)&a);
-    }
-    @property void swizzle(Swizzle rgba) {
-        glTexParameteri(textureTarget, GL_TEXTURE_SWIZZLE_RGBA, rgba);    
-    }
-	
-    @property Swizzle swizzle() {
-        Swizzle rgba;
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_SWIZZLE_R, cast(int*)&rgba);
-        return rgba;
-    }
-    
-    void setWrap(Wrap s, Wrap t, Wrap r) {
-        glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, s); 
-        glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, t); 
-        glTexParameteri(textureTarget, GL_TEXTURE_WRAP_R, r);  
-    }
-	
-    void getWrap(out Wrap s, out Wrap t, out Wrap r) {
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_S, cast(int*)&s);
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_T, cast(int*)&t);
-        glGetTexParameteriv(textureTarget, GL_TEXTURE_WRAP_R, cast(int*)&r);
-    }
-}
-
-
-
-
-
-private void _isTextureUnit(T...)(TextureUnit!(T) t) {}
-enum isTextureUnit(T) = is(typeof(_isTextureUnit(T.init)));
-
-
-
-
-
-
-
-
-
-//==============================================================================
-version(OpenGL4){
-    enum StencilTextureMode : GLenum {
-        DepthComponent = GL_DEPTH_COMPONENT,
-        //TODO: StencilComponent = GL_STENCIL_COMPONENT
-    }
-}
-
-//==============================================================================
-enum CompareFunction : GLenum {
-    LessOrEqual = GL_LEQUAL,
-    GreaterOrEqual = GL_GEQUAL,
-    Less = GL_LESS,
-    Greater = GL_GREATER,
-    Equal = GL_EQUAL,
-    NotEqual = GL_NOTEQUAL,
-    Always = GL_ALWAYS,
-    Never = GL_NEVER       
-}
-
-//==============================================================================
-enum CompareMode : GLenum {
-    CompareRefToTexture = GL_COMPARE_REF_TO_TEXTURE,
-    None = GL_NONE
-}
-
-//==============================================================================
-enum MinFilter : GLenum {
-    Nearest = GL_NEAREST,
-    Linear = GL_LINEAR,
-    NearestMipmapNearest = GL_NEAREST_MIPMAP_NEAREST,
-    LinearMipmapNearest = GL_LINEAR_MIPMAP_NEAREST,
-    NearestMipmapLinear = GL_NEAREST_MIPMAP_LINEAR,
-    LinearMipmapLinear = GL_LINEAR_MIPMAP_LINEAR        
-}
-
-//==============================================================================
-enum MagFilter : GLenum {
-    Nearest = GL_NEAREST,
-    Linear = GL_LINEAR     
-}
-
-//==============================================================================
-enum Swizzle : GLenum {
-    Red = GL_RED, 
-    Green = GL_GREEN, 
-    Blue = GL_BLUE, 
-    Alpha = GL_ALPHA, 
-    Zero = GL_ZERO,
-    One = GL_ONE
-}
-
-//==============================================================================
-enum Wrap : GLenum {
-    ClampToEdge = GL_CLAMP_TO_EDGE, 
-    ClampToBorder = GL_CLAMP_TO_BORDER, 
-    MirroredRepeat = GL_MIRRORED_REPEAT,
-    Repeat = GL_REPEAT
-}
-
-
-
-//==============================================================================
-enum TextureFormat : GLenum {
-	Red = GL_RED,
-	RG = GL_RG,
-	RBG = GL_RGB,
-	BGR = GL_BGR,
-	RGBA = GL_RGBA,
-	BGRA = GL_BGRA,
-	DepthComponent = GL_DEPTH_COMPONENT,
-	StencilIndex = GL_STENCIL_INDEX,
-}
-
-//==============================================================================
-enum TextureType : GLenum {
-	UByte = GL_UNSIGNED_BYTE, 
-	Byte = GL_BYTE,
-	UShort = GL_UNSIGNED_SHORT, 
-	Short = GL_SHORT, 
-	UInt = GL_UNSIGNED_INT, 
-	Int = GL_INT, 
-	Float = GL_FLOAT, 
-	//GL_UNSIGNED_BYTE_3_3_2, 
-	//GL_UNSIGNED_BYTE_2_3_3_REV, 
-	//GL_UNSIGNED_SHORT_5_6_5, 
-	//GL_UNSIGNED_SHORT_5_6_5_REV, 
-	//GL_UNSIGNED_SHORT_4_4_4_4, 
-	//GL_UNSIGNED_SHORT_4_4_4_4_REV, 
-	//GL_UNSIGNED_SHORT_5_5_5_1, 
-	//GL_UNSIGNED_SHORT_1_5_5_5_REV, 
-	//GL_UNSIGNED_INT_8_8_8_8, 
-	//GL_UNSIGNED_INT_8_8_8_8_REV, 
-	//GL_UNSIGNED_INT_10_10_10_2, 
-	//GL_UNSIGNED_INT_2_10_10_10_REV,
-}
-
-
-//==============================================================================
-///
-final class Texture(TextureFormat FORMAT, TextureType TYPE) {
-private:
-	uint _id;
-
-public:		 
-	///
-	this() {
-		check!glGenTextures(1, &this._id);
-		writeln("Texture created: ", this._id);
-	}
-
-	///
-	~this() {
-		check!glDeleteTextures(1, &this._id);
-		writeln("Texture destroyed: ", this._id);
-	}
-	
-public:				
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._id > 0);
-	}
-}
-
-
-private void _isTexture(T...)(Texture!(T) t) {}
-enum isTexture(T) = is(typeof(_isTexture(T.init)));

+ 0 - 298
source/three/gl/util.d

@@ -1,298 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.util;
-
-import std.algorithm;
-import std.stdio;
-import std.stdio : stderr;
-import std.array : join;
-import std.range : repeat;
-import std.string : format;
-import std.traits : ReturnType;
-import derelict.opengl3.gl3;
-
-
-//==============================================================================
-///
-enum BlendMode {
-	Replace,
-	Blend,
-	Add,
-	AddBlended,
-	Mult
-}
-
-
-//==============================================================================
-///
-enum DepthTestMode {
-	None,
-	Always,
-	Equal,
-	Less,
-	Greater,
-	LessEqual,
-	GreaterEqual
-}		 
-
-
-//==============================================================================
-///
-enum CullMode {
-	None,
-	Back,
-	Front
-}
-
-
-//==============================================================================
-///
-void setCullMode(CullMode cm) {
-	final switch(cm) {
-		case CullMode.Back:
-			check!glEnable(GL_CULL_FACE);
-			check!glCullFace(GL_BACK);
-			break;
-		case CullMode.Front:
-			check!glEnable(GL_CULL_FACE);
-			check!glCullFace(GL_FRONT);
-			break;
-		case CullMode.None:
-			check!glDisable(GL_CULL_FACE);
-			break;
-	}
-}
-
-
-//==============================================================================
-///
-void setBlendMode(BlendMode bm) {
-	final switch(bm) {
-		case BlendMode.Replace:
-			glDisable(GL_BLEND);
-			break;
-		case BlendMode.Blend:
-			glEnable(GL_BLEND);
-			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-			break;
-		case BlendMode.Add:
-			glEnable(GL_BLEND);
-			glBlendFunc(GL_ONE, GL_ONE);
-			break;
-		case BlendMode.AddBlended:
-			glEnable(GL_BLEND);
-			glBlendFunc(GL_SRC_ALPHA, GL_ONE);
-			break;
-		case BlendMode.Mult:
-			glEnable(GL_BLEND);
-			glBlendFunc(GL_DST_COLOR, GL_ZERO);
-			break;
-	}
-}			 
-
-
-//==============================================================================
-///
-void setDepthTestMode(DepthTestMode dt) {	
-	glDepthMask(dt == DepthTestMode.None ? GL_FALSE : GL_TRUE);
-	final switch(dt) {
-		case DepthTestMode.None:
-			glDisable(GL_DEPTH_TEST);
-			break;
-		case DepthTestMode.Always:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_ALWAYS);
-			break;
-		case DepthTestMode.Equal:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_EQUAL);
-			break;
-		case DepthTestMode.Less:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_LESS);
-			break;
-		case DepthTestMode.Greater:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_GREATER);
-			break;
-		case DepthTestMode.LessEqual:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_LEQUAL);
-			break;
-		case DepthTestMode.GreaterEqual:
-			glEnable(GL_DEPTH_TEST);
-			glDepthFunc(GL_GEQUAL);
-			break;
-	}
-}
-
-		  
-//==============================================================================
-///
-int maxDrawBuffers() {
-	int maxDrawBuffers;
-	glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
-	return maxDrawBuffers;
-}
-
-
-//==============================================================================
-///
-int maxColorBuffers() {
-	int maxColorBuffers;
-	glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorBuffers);
-	return maxColorBuffers;
-}
-
-
-//==============================================================================
-///
-int maxTextureImageUnits() {
-	int maxTextureImageUnits;
-	glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureImageUnits);
-	return maxTextureImageUnits;
-}
-
-
-//==============================================================================
-///
-ReturnType!func check(alias func, Args...)(Args args) {
-	try{
-		debug scope(exit) {
-			GLenum err = glGetError();
-			if(err != GL_NO_ERROR) {
-				stderr.writefln(`OpenGL function "%s(%s)" failed: "%s."`,
-				func.stringof, format("%s".repeat(Args.length).join(", "), args), gl_error_string(err));
-				assert(false);
-			}
-		}
-	}
-	catch(Exception e){
-	}
-	
-	debug if(func is null) {
-		try{
-			stderr.writefln("%s is null! OpenGL loaded? Required OpenGL version not supported?".format(func.stringof));
-		}
-		catch(Exception e){
-			assert(false);
-		}
-		assert(false);
-	}	
-	return func(args);
-}
-
-
-//==============================================================================
-///
-string gl_error_string(GLenum error) {
-	final switch(error) {
-		case GL_NO_ERROR: return "no error";
-		case GL_INVALID_ENUM: return "invalid enum";
-		case GL_INVALID_VALUE: return "invalid value";
-		case GL_INVALID_OPERATION: return "invalid operation";
-			//case GL_STACK_OVERFLOW: return "stack overflow";
-			//case GL_STACK_UNDERFLOW: return "stack underflow";
-		case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffer operation";
-		case GL_OUT_OF_MEMORY: return "out of memory";
-	}
-	assert(false, "invalid enum");
-}
-
-
-
-
-//~ bool glCheck(string file = __FILE__, int line = __LINE__) @trusted  
-//~ {
-//~ debug{
-	//~ try{
-		//~ int error = glGetError();
-		//~ if (error == GL_NO_ERROR) return true;
-		
-		//~ "[[ %s:%s ]]".writef(file, line);
-		
-		//~ while(error != GL_NO_ERROR) {
-			//~ switch (error) {
-				//~ case GL_INVALID_ENUM:
-					//~ writeln("GL_INVALID_ENUM: an unacceptable value has been specified for an enumerated argument");
-					//~ break;
-				//~ case GL_INVALID_VALUE:
-					//~ writeln("GL_INVALID_VALUE: a numeric argument is out of range");
-					//~ break;
-				//~ case GL_INVALID_OPERATION:
-					//~ writeln("GL_INVALID_OPERATION: the specified operation is not allowed in the current state");
-					//~ break;
-				//~ case GL_OUT_OF_MEMORY:
-					//~ writeln("GL_OUT_OF_MEMORY: there is not enough memory left to execute the command");
-					//~ break;
-				//~ case GL_INVALID_FRAMEBUFFER_OPERATION:
-					//~ writeln("GL_INVALID_FRAMEBUFFER_OPERATION_EXT: the object bound to FRAMEBUFFER_BINDING_EXT is not \"framebuffer complete\"");
-					//~ break;
-				//~ default:
-					//~ writeln("Error not listed. Value: ", error);
-					//~ break;
-			//~ }
-			//~ error = glGetError();
-		//~ }
-	//~ }catch(Exception e)
-	//~ {}
-	//~ return false;
-	//~ }
-	//~ return true;
-//~ }
-
-
-//==============================================================================
-///
-template toGlType(T) {
-	static if(is(T == byte)) {
-		enum toGlType = GL_BYTE;
-	} else static if(is(T == ubyte)) {
-		enum toGlType = GL_UNSIGNED_BYTE;
-	} else static if(is(T == short)) {
-		enum toGlType = GL_SHORT;
-	} else static if(is(T == ushort)) {
-		enum toGlType = GL_UNSIGNED_SHORT;
-	} else static if(is(T == int)) {
-		enum toGlType = GL_INT;
-	} else static if(is(T == uint)) {
-		enum toGlType = GL_UNSIGNED_INT;
-	} else static if(is(T == float)) {
-		enum toGlType = GL_FLOAT;
-	} else static if(is(T == double)) {
-		enum toGlType = GL_DOUBLE;
-	} else {
-		static assert(false, T.stringof ~ " cannot be represented as GLenum");
-	}
-}
-
-
-//==============================================================================
-///
-template sizeofGlType(GLenum t) {
-	static if(t == GL_BYTE) {
-		enum sizeofGlType = byte.sizeof;
-	} else static if(t == GL_UNSIGNED_BYTE) {
-		enum sizeofGlType = ubyte.sizeof;
-	} else static if(t == GL_SHORT) {
-		enum sizeofGlType = short.sizeof;
-	} else static if(t == GL_UNSIGNED_SHORT) {
-		enum sizeofGlType = ushort.sizeof;
-	} else static if(t == GL_INT) {
-		enum sizeofGlType = int.sizeof;
-	} else static if(t == GL_UNSIGNED_INT) {
-		enum sizeofGlType = uint.sizeof;
-	} else static if(t == GL_FLOAT) {
-		enum sizeofGlType = float.sizeof;
-	} else static if(t == GL_DOUBLE) {
-		enum sizeofGlType = double.sizeof;
-	} else {
-		static assert(false, T.stringof ~ " cannot be represented as D-Type");
-	}
-}

+ 0 - 52
source/three/gl/vao.d

@@ -1,52 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.vao;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-import std.stdio;
-//==============================================================================
-///
-final class VertexArrayObject {
-private:
-	uint _id;
-
-public:	   
-	///
-	this() {
-		check!glGenVertexArrays(1, &this._id);
-		writeln("vao created: ", this._id);
-	}
-
-	///
-	~this() {
-		writeln("vao destroxing..: ", this._id);
-		check!glDeleteVertexArrays(1, &this._id);
-		writeln("vao destroyed: ", this._id);
-	}
-	
-public:		   
-	///
-	void bind() { 
-		assert(this.isValid);
-		check!glBindVertexArray(this._id);
-	}
-
-	///
-	static void unbind() { 
-		check!glBindVertexArray(0);
-	}  
-	
-public:	  
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._id > 0);
-	}
-}

+ 0 - 89
source/three/gl/vbo.d

@@ -1,89 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.gl.vbo;
-
-import derelict.opengl3.gl3;
-import three.gl.util;
-
-
-//==============================================================================
-///
-enum VertexBufferObjectTarget {
-	Array = GL_ARRAY_BUFFER, 
-	AtomicCounter = GL_ATOMIC_COUNTER_BUFFER, 
-	CopyRead= GL_COPY_READ_BUFFER, 
-	CopyWrite = GL_COPY_WRITE_BUFFER, 
-	DrawIndirect = GL_DRAW_INDIRECT_BUFFER, 
-	DispatchIndirect = GL_DISPATCH_INDIRECT_BUFFER,
-	ElementArray = GL_ELEMENT_ARRAY_BUFFER, 
-	PixelPack = GL_PIXEL_PACK_BUFFER, 
-	PixelUnpack = GL_PIXEL_UNPACK_BUFFER, 
-	ShaderStorage = GL_SHADER_STORAGE_BUFFER,
-	Texture = GL_TEXTURE_BUFFER, 
-	TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
-	Uniform = GL_UNIFORM_BUFFER
-}
-
-
-//==============================================================================
-///
-enum BufferUsageHint {
-	StreamDraw = GL_STREAM_DRAW, 
-	StreamRead = GL_STREAM_READ, 
-	StreamCopy = GL_STREAM_COPY, 
-	StaticDraw = GL_STATIC_DRAW, 
-	StaticRead = GL_STATIC_READ, 
-	StaticCopy = GL_STATIC_COPY, 
-	DynamicDraw = GL_DYNAMIC_DRAW, 
-	DynamicRead = GL_DYNAMIC_READ, 
-	DynamicCopy = GL_DYNAMIC_COPY
-}
-
-import std.stdio;
-//==============================================================================
-///
-final class VertexBufferObject(VertexBufferObjectTarget target) {
-private:
-	uint _id;
-
-public:		   
-	///
-	this() {
-		check!glGenBuffers(1, &this._id);
-		writeln("vbo created: ", this._id);
-	}
-
-	///
-	~this() {
-		check!glDeleteBuffers(1, &this._id);
-		writeln("vbo destroyed: ", this._id);
-	}
-	
-public:		 
-	///
-	void bind() { 
-		assert(this.isValid);
-		check!glBindBuffer(target, this._id);
-	}
-
-	///
-	static unbind() { 
-		check!glBindBuffer(target, 0);
-	}  
-	
-public:			
-	///
-	@property bool isValid() const @safe nothrow {
-		return (this._id > 0);
-	}
-}
-
-
-private void _isVertexBufferObject(T...)(VertexBufferObject!(T) t) {}
-enum isVertexBufferObject(T) = is(typeof(_isVertexBufferObject(T.init)));

+ 0 - 11
source/three/glfw/package.d

@@ -1,11 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.glfw;
-
-public import three.glfw.window;

+ 0 - 439
source/three/glfw/window.d

@@ -1,439 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.glfw.window;
-
-import derelict.opengl3.gl3;
-import derelict.glfw3.glfw3;
-
-import std.string;
-import stdx.signals;
-
-import std.stdio;
-
-//==============================================================================
-///
-alias WindowRect = uint[4];
-
-
-//==============================================================================
-///
-void updateWindows() {
-	glfwPollEvents();
-}
-
-
-//==============================================================================
-///
-final class Window {
-package:
-	GLFWwindow* _glfwWindow = null;	
-	uint _x, _y, _w, _h;
-	string _title;					 
-	KeyAction[int] _keyStates;
-	ButtonAction[int] _buttonStates;
-
-public:			 
-	///
-	this(string title, uint width, uint height) {
-		glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-		glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
-		glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
-
-		glfwDefaultWindowHints();
-		glfwWindowHint(GLFW_RED_BITS, 8);
-		glfwWindowHint(GLFW_GREEN_BITS, 8);
-		glfwWindowHint(GLFW_BLUE_BITS, 8);
-		glfwWindowHint(GLFW_ALPHA_BITS, 0);
-		glfwWindowHint(GLFW_DEPTH_BITS, 24);
-		glfwWindowHint(GLFW_STENCIL_BITS, 8);
-		//~ glfwWindowHint(GLFW_FSAA_SAMPLES, 0); 
-		
-		this._glfwWindow = glfwCreateWindow(width, height, title.toStringz(), null, null);
-		assert(this._glfwWindow !is null);
-
-		glfwSetWindowUserPointer(this._glfwWindow, cast(void*)this);
-		glfwSetWindowPosCallback(this._glfwWindow, cast(GLFWwindowposfun)&_GLFWwindowposfun);
-		glfwSetWindowSizeCallback(this._glfwWindow, cast(GLFWwindowsizefun)&_GLFWwindowsizefun);
-		glfwSetWindowCloseCallback(this._glfwWindow, cast(GLFWwindowclosefun)&_GLFWwindowclosefun);
-		glfwSetWindowRefreshCallback(this._glfwWindow, cast(GLFWwindowrefreshfun)&_GLFWwindowrefreshfun);
-		glfwSetWindowIconifyCallback(this._glfwWindow, cast(GLFWwindowiconifyfun)&_GLFWwindowiconifyfun);
-		glfwSetMouseButtonCallback(this._glfwWindow, cast(GLFWmousebuttonfun)&_GLFWmousebuttonfun);
-		glfwSetCursorPosCallback(this._glfwWindow, cast(GLFWcursorposfun)&_GLFWcursorposfun);
-		//glfwSetCursorEnterCallback(this._glfwWindow, cast(GLFWcursorenterfunfun)&_GLFWcursorenterfunfun);
-		glfwSetScrollCallback(this._glfwWindow, cast(GLFWscrollfun)&_GLFWscrollfun);
-		glfwSetKeyCallback(this._glfwWindow, cast(GLFWkeyfun)&_GLFWkeyfun);
-		glfwSetCharCallback(this._glfwWindow, cast(GLFWcharfun)&_GLFWcharfun);
-
-		this.makeAktiveRenderWindow();
-		this.clear(1,0,0,1);
-		writeln("Window created: ", this._glfwWindow);
-	}
-
-	///
-	~this() {
-		glfwSetWindowPosCallback(this._glfwWindow, null);
-		glfwSetWindowSizeCallback(this._glfwWindow, null);
-		glfwSetWindowCloseCallback(this._glfwWindow, null);
-		glfwSetWindowRefreshCallback(this._glfwWindow, null);
-		glfwSetWindowIconifyCallback(this._glfwWindow, null);
-		glfwSetMouseButtonCallback(this._glfwWindow, null);
-		glfwSetCursorPosCallback(this._glfwWindow, null);
-		//glfwSetCursorEnterCallback(this._glfwWindow, null);
-		glfwSetScrollCallback(this._glfwWindow, null);
-		glfwSetKeyCallback(this._glfwWindow, null);
-		glfwSetCharCallback(this._glfwWindow, null);
-
-		glfwDestroyWindow(this._glfwWindow);
-		writeln("Window destroyed: ", this._glfwWindow);
-	}
-
-public:		  
-	///
-	KeyAction keyState(int key) const {
-		return _keyStates.get(key, KeyAction.Released);
-	}
-
-	///
-	ButtonAction buttonState(int button) const {
-		return _buttonStates.get(button, ButtonAction.Released);
-	}
-
-public:		
-	///
-	void clear(float r, float g, float b, float a, float depth = 1.0f, GLenum bits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) {
-		glClearColor(r, g, b, a);
-		glClearDepth(depth);
-		glClear(bits);
-	}
-
-	///
-	void swapBuffers() {
-		glfwSwapBuffers(this._glfwWindow);	
-	}
-
-	///
-	void makeAktiveRenderWindow() {
-		glfwMakeContextCurrent(this._glfwWindow);
-	}
-
-	uint x() const @safe nothrow {
-		return _x;
-	}	
-
-	uint y() const @safe nothrow {
-		return _y;
-	}
-
-	uint width() const @safe nothrow {
-		return _w;
-	}	
-	
-	uint height() const @safe nothrow {
-		return _h;
-	}
-
-	///
-	@property void title(string title) {
-		glfwSetWindowTitle(this._glfwWindow, title.toStringz());
-	}
-
-public:								 
-	///
-	Signal!(Window, int, int) onPosition;	 
-	///
-	Signal!(Window, int, int) onSize;	  
-	///
-	Signal!(Window) onClose;			 
-	///
-	Signal!(Window) onRefresh;			
-	///
-	Signal!(Window, FocusAction) onFocus;	  
-	///
-	Signal!(Window, IconifyAction) onIconify;	
-	///
-	Signal!(Window, bool) onCursorEnter;		
-	///
-	Signal!(Window, int, ButtonAction) onButton;	
-	/// 
-	Signal!(Window, double, double) onCursorPos; 
-	///
-	Signal!(Window, double, double) onScroll;	
-	///
-	Signal!(Window, Key, ScanCode, KeyAction, KeyMod) onKey;   
-	///
-	Signal!(Window, int) onChar;
-}
-
-
-//==============================================================================
-///
-alias ScanCode = int;
-
-
-//==============================================================================
-///
-enum IconifyAction {
-	Iconified,
-	Restored
-}
-
-
-//==============================================================================
-///
-enum FocusAction {
-	Focused,
-	Defocused
-}
-
-
-//==============================================================================
-///
-enum CursorAction {
-	Entered,
-	Leaved
-}
-
-
-//==============================================================================
-///
-enum ButtonAction {
-	Pressed,
-	Released
-}
-
-
-//==============================================================================
-///
-enum KeyAction {
-	Pressed,
-	Released,
-	Repeated
-}
-
-
-//==============================================================================
-///
-enum KeyMod {
-	Shift = 0x0001,
-	Control = 0x0002,
-	Alt = 0x0004,
-	Super = 0x0008,
-}
-
-
-//==============================================================================
-///
-enum Key {
-	Unknown = -1,
-	Space = 32,
-	Apostrophe = 39,
-	Comma = 44,
-	Minus = 45,
-	Period = 46,
-	Slash = 47,
-	Key0 = 48,
-	Key1 = 49,
-	Key2 = 50,
-	Key3 = 51,
-	Key4 = 52,
-	Key5 = 53,
-	Key6 = 54,
-	Key7 = 55,
-	Key8 = 56,
-	Key9 = 57,
-	Semicolon = 59,
-	Equal = 61,
-	KeyA = 65,
-	KeyB = 66,
-	KeyC = 67,
-	KeyD = 68,
-	KeyE = 69,
-	KeyF = 70,
-	KeyG = 71,
-	KeyH = 72,
-	KeyI = 73,
-	KeyJ = 74,
-	KeyK = 75,
-	Keyl = 76,
-	KeyM = 77,
-	KeyN = 78,
-	KeyO = 79,
-	KeyP = 80,
-	KeyQ = 81,
-	KeyR = 82,
-	KeyS = 83,
-	KeyT = 84,
-	KeyU = 85,
-	KeyV = 86,
-	KeyW = 87,
-	KeyX = 88,
-	KeyY = 89,
-	KeyZ = 90,
-	LeftBracket = 91,
-	Backslash = 92,
-	RightBracket = 93,
-	GraveAccent = 96,
-	World1 = 161,
-	World2 = 162,
-	Escape = 256,
-	Enter = 257,
-	Tab = 258,
-	Backspace = 259,
-	Insert = 260,
-	Delete = 261,
-	Right = 262,
-	Left = 263,
-	Down = 264,
-	Up = 265,
-	PageUp = 266,
-	PageDown = 267,
-	Home = 268,
-	End = 269,
-	CapsLock = 280,
-	ScrollLock = 281,
-	NumLock = 282,
-	PrintScreen = 283,
-	Pause = 284,
-	F1 = 290,
-	F2 = 291,
-	F3 = 292,
-	F4 = 293,
-	F5 = 294,
-	F6 = 295,
-	F7 = 296,
-	F8 = 297,
-	F9 = 298,
-	F10 = 299,
-	F11 = 300,
-	F12 = 301,
-	F13 = 302,
-	F14 = 303,
-	F15 = 304,
-	F16 = 305,
-	F17 = 306,
-	F18 = 307,
-	F19 = 308,
-	F20 = 309,
-	F21 = 310,
-	F22 = 311,
-	F23 = 312,
-	F24 = 313,
-	F25 = 314,
-	NumBlock0 = 320,
-	NumBlock1 = 321,
-	NumBlock2 = 322,
-	NumBlock3 = 323,
-	NumBlock4 = 324,
-	NumBlock5 = 325,
-	NumBlock6 = 326,
-	NumBlock7 = 327,
-	NumBlock8 = 328,
-	NumBlock9 = 329,
-	KpDecimal = 330,
-	KpDivide = 331,
-	KpMultiply = 332,
-	KpSubtract = 333,
-	KpAdd = 334,
-	KpEnter = 335,
-	KpEqual = 336,
-	LeftShift = 340,
-	LeftControl = 341,
-	LeftAlt = 342,
-	LeftSuper = 343,
-	RightShift = 344,
-	RightControl = 345,
-	RightAlt = 346,
-	RightSuper = 347,
-	Menu = 348
-}
-
-
-
-
-private Window _castWindow(GLFWwindow* window)
-out (result) { assert(result !is null, "glfwGetWindowUserPointer returned null"); }
-body {
-	void* user_ptr = glfwGetWindowUserPointer(window);
-	return cast(Window)user_ptr;
-}
-
-
-private extern(C) void _GLFWwindowposfun(GLFWwindow* glfwWindow, int x, int y) {							  
-	Window window = _castWindow(glfwWindow);
-	auto monitor = glfwGetPrimaryMonitor();
-	if(monitor is null) return;
-	auto videoMode = glfwGetVideoMode(monitor);
-	y = videoMode.height - y;
-	int w,h;
-	glfwGetWindowSize(glfwWindow, &w, &h);
-	window._x = x;
-	window._y = y;
-	window._w = w;
-	window._h = h;
-	window.onPosition.emit(window, x, y);
-}
-
-private extern(C) void _GLFWwindowsizefun(GLFWwindow* glfwWindow, int width, int height) {												 
-	Window window = _castWindow(glfwWindow);
-	window._w = width;
-	window._h = height;
-	window.onSize.emit(window, width, height);
-}
-
-private extern(C) void _GLFWwindowclosefun(GLFWwindow* glfwWindow) {				  
-	Window window = _castWindow(glfwWindow);
-	window.onClose.emit(window);
-}
-
-private extern(C) void _GLFWwindowrefreshfun(GLFWwindow* glfwWindow) {													 
-	Window window = _castWindow(glfwWindow);
-	window.onRefresh.emit(window);
-}
-
-private extern(C) void _GLFWwindowfocusfun(GLFWwindow* glfwWindow, int focused) {													 
-	Window window = _castWindow(glfwWindow);
-	window.onFocus.emit(window, (focused == GL_TRUE) ? FocusAction.Focused : FocusAction.Defocused);
-}
-
-private extern(C) void _GLFWwindowiconifyfun(GLFWwindow* glfwWindow, int iconified) {												 
-	Window window = _castWindow(glfwWindow);
-	window.onIconify.emit(window, (iconified == GL_TRUE) ? IconifyAction.Iconified : IconifyAction.Restored);
-}
-
-private extern(C) void _GLFWcursorenterfun(GLFWwindow* glfwWindow, int entered) {
-	Window window = _castWindow(glfwWindow);
-	window.onCursorEnter.emit(window, (entered == GL_TRUE) ? CursorAction.Entered : CursorAction.Leaved);
-}
-
-private extern(C) void _GLFWmousebuttonfun(GLFWwindow* glfwWindow, int button, int action) { 
-	Window window = _castWindow(glfwWindow);
-	window._buttonStates[button] = (action == GLFW_PRESS) ? ButtonAction.Pressed : ButtonAction.Released;
-	window.onButton.emit(window, button, (action == GLFW_PRESS) ? ButtonAction.Pressed : ButtonAction.Released);
-}
-
-private extern(C) void _GLFWcursorposfun(GLFWwindow* glfwWindow, double x, double y) {
-	Window window = _castWindow(glfwWindow);
-	window.onCursorPos.emit(window, x, window._h - y);
-}
-
-private extern(C) void _GLFWscrollfun(GLFWwindow* glfwWindow, double x, double y) {	
-	Window window = _castWindow(glfwWindow);
-	window.onScroll.emit(window, x, y);
-}
-
-private extern(C) void _GLFWkeyfun(GLFWwindow* glfwWindow, int key, int scancode, int action, int mods) {  
-	Window window = _castWindow(glfwWindow);
-	window._keyStates[key] = (action == GLFW_PRESS || action == GLFW_REPEAT) ? KeyAction.Pressed : KeyAction.Released;
-	window.onKey.emit(window, cast(Key)key, cast(ScanCode)scancode, cast(KeyAction)action, cast(KeyMod)mods);
-}
-
-private extern(C) void _GLFWcharfun(GLFWwindow* glfwWindow, uint character) { 
-	Window window = _castWindow(glfwWindow);
-	window.onChar.emit(window, character);
-}

+ 0 - 72
source/three/init.d

@@ -1,72 +0,0 @@
-module three.init;
-
-import derelict.opengl3.gl3;
-import derelict.glfw3.glfw3;
-import derelict.anttweakbar.anttweakbar;
-import derelict.freeimage.freeimage;	
-import derelict.freetype.ft;
-import derelict.assimp3.assimp;
-
-import three.glfw.window;
-
-import std.stdio;
-import std.conv;
-
-
-private static FT_Library _s_freeTypeLibrary;
-
-Window initThree() {
-	"Starting Three.d".writeln();
-
-	"Loading OpenGL".writeln();
-	DerelictGL3.load();
-
-	"Loading GLFW".writeln();
-	DerelictGLFW3.load();
-
-	"Loading FreeImage".writeln();
-	DerelictFI.load();	  
-
-//	"Loading FreeType".writeln();
-//	DerelictFT.load();
-
-	"Loading Assimp".writeln();
-	DerelictASSIMP3.load();
-
-	"Loading AntTweakBar".writeln();
-	DerelictAntTweakBar.load();
-
-	"Initialising GLFW".writeln();
-	if(!glfwInit()) throw new Exception("Initialising GLFW failed");
-
-	"Creating Window".writeln();
-	auto window = new Window("Fray", 1600, 900);
-	
-	"ReLoading OpenGL".writeln();
-	try {
-		GLVersion glVersion = DerelictGL3.reload();
-		writeln("Loaded OpenGL Version", to!string(glVersion));
-	} catch(Exception e) {
-		writeln("exception: "~ e.msg);
-	}
-
-//	"Initialising FreeType".writeln();
-//	if(!FT_Init_FreeType(&_s_freeTypeLibrary)) throw new Exception("Initialising FreeType failed");
-
-	"Initialising AntTweakBar".writeln();
-	if(TwInit(TW_OPENGL_CORE, null) == 0) throw new Exception("Initialising AntTweakBar failed");
-
-	return window;
-}
-
-void deinitThree() { 
-
-	"Terminating AntTweakBar".writeln();
-	TwTerminate();
-
-//	"Terminating FreeType".writeln();
-//	FT_Done_FreeType(_s_freeTypeLibrary);
-
-	"Terminating GLFW".writeln();
-	glfwTerminate();	
-}

+ 127 - 0
source/three/mesh.d

@@ -0,0 +1,127 @@
+module three.mesh;
+
+import three.common;
+
+struct SOAMesh {
+	SoA!GLuint vao;
+	SoA!GLuint vboVertices;
+	SoA!GLuint vboNormals;
+	SoA!GLuint vboTexcoords;
+	SoA!GLuint vboColors;
+	SoA!GLuint vboIndices;
+	SoA!GLuint cntIndices;
+	size_t cnt;
+}
+
+void loadModel(ref SOAMesh mesh, string filePath) {
+	import std.traits;
+	import std.string : toStringz;
+	auto scene = aiImportFile(filePath.toStringz(),	aiProcess_Triangulate); scope(exit) aiReleaseImport(scene);
+	
+	for(uint m = 0; m < scene.mNumMeshes; ++m) {	
+		const(aiMesh*) meshData = scene.mMeshes[m];
+		assert(meshData !is null);
+		
+		//-----------------------------
+		// create mesh
+		auto meshIdx = mesh.cnt;
+		++mesh.cnt;
+		mesh.vao.length = mesh.cnt;
+		mesh.vboVertices.length = mesh.cnt;
+		mesh.vboNormals.length = mesh.cnt;
+		mesh.vboTexcoords.length = mesh.cnt;
+		mesh.vboIndices.length = mesh.cnt;
+		mesh.cntIndices.length = mesh.cnt;
+		
+		//-----------------------------
+		// upload data
+		glCheck!glGenVertexArrays(1, &mesh.vao[meshIdx]);
+		glCheck!glBindVertexArray(mesh.vao[meshIdx]); scope(exit) glCheck!glBindVertexArray(0);
+		
+		alias Vertex = float[3];
+		alias Normal = float[3];
+		alias TexCoord = float[2];
+		alias Color = float[4];
+		alias Index = uint[1];
+		
+		size_t cntIndices = 0;
+		foreach(f; 0..meshData.mNumFaces) {
+			cntIndices += meshData.mFaces[f].mNumIndices;				
+		}
+		
+		{// upload vertex data
+			Vertex[] vertexData;
+			vertexData.length = meshData.mNumVertices;
+			foreach(v; 0..meshData.mNumVertices) {
+				vertexData[v] = [meshData.mVertices[v].x, meshData.mVertices[v].y, meshData.mVertices[v].z];
+			}
+			glCheck!glGenBuffers(1, &mesh.vboVertices[meshIdx]);
+			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboVertices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
+			GLuint attribIndex = 0;
+			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Vertex.sizeof * vertexData.length) , vertexData.ptr, GL_STATIC_DRAW);		
+			glCheck!glEnableVertexAttribArray(attribIndex);
+			glCheck!glVertexAttribPointer(attribIndex, Vertex.sizeof / ForeachType!Vertex.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
+		}
+		
+		{// upload normal data
+			Normal[] normalData;
+			normalData.length = meshData.mNumVertices;
+			foreach(v; 0..meshData.mNumVertices) {
+				normalData[v] = [meshData.mNormals[v].x, meshData.mNormals[v].y, meshData.mNormals[v].z];
+			}
+			glCheck!glGenBuffers(1, &mesh.vboNormals[meshIdx]);
+			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboNormals[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
+			GLuint attribIndex = 1;
+			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Normal.sizeof * normalData.length) , normalData.ptr, GL_STATIC_DRAW);		
+			glCheck!glEnableVertexAttribArray(attribIndex);
+			glCheck!glVertexAttribPointer(attribIndex, Normal.sizeof / ForeachType!Normal.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
+		}
+		
+		if(meshData.mTextureCoords[0] !is null) {// upload texture data
+			TexCoord[] textureData;
+			textureData.length = meshData.mNumVertices;
+			foreach(v; 0..meshData.mNumVertices) {
+				textureData[v] = [meshData.mTextureCoords[0][v].x, meshData.mTextureCoords[0][v].y];
+			}
+			glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
+			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
+			GLuint attribIndex = 2;
+			glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(TexCoord.sizeof * textureData.length) , textureData.ptr, GL_STATIC_DRAW);		
+			glEnableVertexAttribArray(attribIndex);
+			glVertexAttribPointer(attribIndex, TexCoord.sizeof / ForeachType!TexCoord.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
+		}
+		
+		if(meshData.mColors[0] !is null) {// upload color data
+			Color[] colorData;
+			colorData.length = meshData.mNumVertices;
+			foreach(v; 0..meshData.mNumVertices) {
+				colorData[v] = [meshData.mColors[0][v].r, meshData.mColors[0][v].g, meshData.mColors[0][v].b, meshData.mColors[0][v].a];
+			}
+			glCheck!glGenBuffers(1, &mesh.vboTexcoords[meshIdx]);
+			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboTexcoords[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
+			GLuint attribIndex = 2;
+			glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Color.sizeof * colorData.length) , colorData.ptr, GL_STATIC_DRAW);		
+			glEnableVertexAttribArray(attribIndex);
+			glVertexAttribPointer(attribIndex, Color.sizeof / ForeachType!Color.sizeof, GL_FLOAT, GL_FALSE, 0, cast(void*)0);
+		}
+		
+		{// upload index data
+			Index[] indexData;
+			indexData.length = cntIndices;
+			size_t curIndexDataIdx = 0;
+			foreach(f; 0..meshData.mNumFaces) {
+				assert(meshData.mFaces !is null);
+				foreach(i; 0..meshData.mFaces[f].mNumIndices) {
+					assert(meshData.mFaces[f].mIndices !is null);
+					indexData[curIndexDataIdx++] = meshData.mFaces[f].mIndices[i];		
+				}
+			}
+			glCheck!glGenBuffers(1, &mesh.vboIndices[meshIdx]);
+			glCheck!glBindBuffer(GL_ARRAY_BUFFER, mesh.vboIndices[meshIdx]); scope(exit) glCheck!glBindBuffer(GL_ARRAY_BUFFER, 0); 
+			GLuint attribIndex = 3;
+			glCheck!glBufferData(GL_ARRAY_BUFFER, cast(ptrdiff_t)(Index.sizeof * indexData.length) , indexData.ptr, GL_STATIC_DRAW);		
+			glCheck!glEnableVertexAttribArray(attribIndex);
+			glCheck!glVertexAttribPointer(attribIndex, Index.sizeof / ForeachType!Index.sizeof, GL_UNSIGNED_INT, GL_FALSE, 0, cast(void*)0);
+		}
+	}
+}

+ 9 - 6
source/three/package.d

@@ -1,7 +1,10 @@
-module three;
+module three;
 
-public import three.gfx;
-public import three.gl;
-public import three.glfw;
-public import three.primitives;
-public import three.init;
+public import three.camera;
+public import three.common;
+public import three.mesh;
+public import three.renderer;
+public import three.renderTarget;
+public import three.scene;
+public import three.viewport;
+public import three.window;

+ 0 - 92
source/three/primitives/color.d

@@ -1,92 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.primitives.color;
-
-import std.typecons;
-import std.typetuple;
-import std.conv;
-
-struct RedColorComponent(T) { T r; alias r this; this(T t){r=t;} }
-struct GreenColorComponent(T) { T g; alias g this; this(T t){g=t;} }
-struct BlueColorComponent(T) { T b; alias b this; this(T t){b=t;} }
-struct AlphaColorComponent(T) { T a; alias a this; this(T t){a=t;} }
-
-///
-enum isRedColorComponent(T) = is(typeof(_isRedColorComponent(T.init)));
-private void _isRedColorComponent(T)(RedColorComponent!(T) t) {}
-///
-enum isGreenColorComponent(T) = is(typeof(_isGreenColorComponent(T.init)));
-private void _isGreenColorComponent(T)(GreenColorComponent!(T) t) {}
-///
-enum isBlueColorComponent(T) = is(typeof(_isBlueColorComponent(T.init)));
-private void _isBlueColorComponent(T)(BlueColorComponent!(T) t) {}	
-///
-enum isAlphaColorComponent(T) = is(typeof(_isAlphaColorComponent(T.init)));
-private void _isAlphaColorComponent(T)(AlphaColorComponent!(T) t) {}
-
-enum isRGBColorComponent(T) = isRedColorComponent!T || isGreenColorComponent!T || isBlueColorComponent!T;
-enum isRGBAColorComponent(T) = isRGBColorComponent!T || isAlphaColorComponent!T;
-
-enum hasRedColorComponent(T...) = anySatisfy!(isRedColorComponent, T);
-enum hasGreenColorComponent(T...) = anySatisfy!(isGreenColorComponent, T);
-enum hasBlueColorComponent(T...) = anySatisfy!(isBlueColorComponent, T);
-enum hasAlphaColorComponent(T...) = anySatisfy!(isAlphaColorComponent, T);
-
-enum isRGB(T...) = T.length == 3 && isRedColorComponent!(T[0]) && isGreenColorComponent!(T[1]) && isBlueColorComponent!(T[2]);  
-enum isRGBA(T...) = T.length == 4 && isRGB!(T[0..3]) && isAlphaColorComponent!(T[3]);
-enum isARGB(T...) = T.length == 4 && isAlphaColorComponent!(T[3]) && isRGB!(T[0..3]);
-
-enum isBGR(T...) = T.length == 3 && isBlueColorComponent!(T[0]) && isGreenColorComponent!(T[1]) && isRedColorComponent!(T[2]);  
-enum isBGRA(T...) = T.length == 4 && isBGR!(T[0..3]) && isAlphaColorComponent!(T[3]);
-enum isABGR(T...) = T.length == 4 && isAlphaColorComponent!(T[3]) && isBGR!(T[0..3]);
-																 
-alias RGBColorComponents(T) = TypeTuple!(RedColorComponent!T, GreenColorComponent!T, BlueColorComponent!T);						   
-alias RGBAColorComponents(T) = TypeTuple!(RGBColorComponents!T, AlphaColorComponent!T);
-alias ARGBColorComponents(T) = TypeTuple!(AlphaColorComponent!T, RGBColorComponents!T);
-																	
-alias BGRColorComponents(T) = TypeTuple!(BlueColorComponent!T, GreenColorComponent!T, RedColorComponent!T);						   
-alias BGRAColorComponents(T) = TypeTuple!(BGRColorComponents!T, AlphaColorComponent!T);
-alias ABGRColorComponents(T) = TypeTuple!(AlphaColorComponent!T, BGRColorComponents!T);
-
-
-enum isValidColorComponentDefinition(T...) = allSatisfy!(isRGBAColorComponent, T) && NoDuplicates!(T).length == T.length;
-
-static assert(isValidColorComponentDefinition!(RGBAColorComponents!float));
-
-private string _genMembers(size_t IDX, N...)() {
-	string ret;
-	foreach(K; N) {
-		ret ~= "alias " ~ K ~ " = _components[" ~ to!string(IDX-1) ~ "];\n";	  
-	}
-	return ret;
-}		
-
-private mixin template _GenAccessors(size_t IDX, T...) if(T.length > 0) {
-	static if(T.length == 1) {
-		mixin(_genMembers!(IDX, __traits(allMembers, T[0]))());
-	}
-	else {					
-		mixin _GenAccessors!(IDX+1, T[0]);	
-		mixin _GenAccessors!(IDX+1, T[1..$]);	
-	}
-}
-
-struct Color(COMPONENTS...) if(COMPONENTS.length > 0 && isValidColorComponentDefinition!COMPONENTS) {
-	COMPONENTS _components;		
-
-	this(T...)(T t) {
-		this._components[] = t[];
-	}
-
-	mixin _GenAccessors!(0, COMPONENTS);  
-}
-
-
-alias RGBAf = Color!(RGBAColorComponents!float);
-alias RGBf = Color!(RGBAColorComponents!float);

+ 0 - 13
source/three/primitives/package.d

@@ -1,13 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.primitives;
-public import three.primitives.color;
-public import three.primitives.point;
-public import three.primitives.quaternion;
-public import three.primitives.rect;

+ 0 - 58
source/three/primitives/point.d

@@ -1,58 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.primitives.point;
-
-import std.traits;
-
-struct Vector(size_t D, T) if(D > 0 && isNumeric!T) {
-public:
-	T[D] data;
-	
-	alias data this;
-
-	this(T[] data...) {
-		this.data = data;
-	}
-	
-	static if(D >= 1) {
-		T x() @safe @property const {
-			return data[0];
-		}
-		
-		void x(T t) @safe @property {
-			data[0] = t;
-		}
-	}
-	
-	static if(D >= 2) {
-		T y() @safe @property const {
-			return data[1];
-		}
-		
-		void y(T t) @safe @property {
-			data[1] = t;
-		}
-	}
-	
-	static if(D >= 3) {
-		T z() @safe @property const {
-			return data[2];
-		}
-		
-		void z(T t) @safe @property {
-			data[2] = t;
-		}
-	}
-}
-
-alias Vector2f = Vector!(2, float);
-alias Vector3f = Vector!(3, float);
-
-alias Point2f = Vector2f;
-alias Point3f = Vector3f;

+ 0 - 9
source/three/primitives/quaternion.d

@@ -1,9 +0,0 @@
-module three.primitives.quaternion;
-
-import std.traits;
-
-struct Quaternion(T) if(isFloatingPoint!T) {
-	float x, y, z, w;
-}
-
-alias Quaternionf = Quaternion!(float);

+ 0 - 137
source/three/primitives/rect.d

@@ -1,137 +0,0 @@
-// Written in the D programming language.
-/**						   
-Copyright: Copyright Felix 'Zoadian' Hufnagel 2014-.
-
-License:   $(WEB http://www.gnu.org/licenses/lgpl.html, LGPLv3).
-
-Authors:   $(WEB zoadian.de, Felix 'Zoadian' Hufnagel)
-*/
-module three.primitives.rect;
-
-import three.primitives.point;
-
-import std.traits;
-
-/**
-	+-------->   x
-	|
-	|
-	|
-	|
-	v
-	
-	y
-	
-*/
-struct Rect2(T) if(isNumeric!T) {
-private:
-	T[4] data; //l,t,r,b
-
-public:	
-	///
-	T x() const @safe nothrow @property {
-		return this.left;
-	}
-	
-	///
-	T y() const @safe nothrow @property {
-		return this.top;
-	}
-	
-public:	
-	///
-	T left() const @safe nothrow @property {
-		return data[0];
-	}
-	
-	///
-	T top() const @safe nothrow @property {
-		return data[1];
-	}
-	
-	///
-	T right() const @safe nothrow @property {
-		return data[2];
-	}	
-	
-	///
-	T bottom() const @safe nothrow @property {
-		return data[3];
-	}
-	
-public:	
-	///
-	T width() const @safe nothrow @property { 
-		return this.right - this.left;
-	}
-	
-	///
-	T height() const @safe nothrow @property { 
-		return this.bottom - this.top;
-	}
-	
-public:	
-	///
-	Point!(2,T) center() const @safe nothrow @property {
-		return Point!(2,T)(this.x + this.width / 2, this.y + this.height / 2);
-	}		
-	
-	///
-	Point!(2,T) leftTop() const @safe nothrow @property {
-		return Point!(2,T)(this.left, this.top);
-	}
-	
-	///
-	Point!(2,T) rightTop() const @safe nothrow @property {
-		return Point!(2,T)(this.right, this.top);
-	}	
-	
-	///
-	Point!(2,T) rightBottom() const @safe nothrow @property {
-		return Point!(2,T)(this.right, this.bottom);
-	}	
-	
-	///
-	Point!(2,T) leftBottom() const @safe nothrow @property {
-		return Point!(2,T)(this.left, this.bottom);
-	}	
-}
-
-
-///
-struct RectOffset2(T) if(isNumeric!T) {
-private:
-	T[4] data; //l,t,r,b
-	
-public:	
-	///
-	T left() const @safe nothrow @property {
-		return data[0];
-	}
-	
-	///
-	T top() const @safe nothrow @property {
-		return data[1];
-	}
-	
-	///
-	T right() const @safe nothrow @property {
-		return data[2];
-	}	
-	
-	///
-	T bottom() const @safe nothrow @property {
-		return data[3];
-	}
-	
-public:	
-	/// equal to left + right
-	T horizontal() const @safe nothrow @property {
-		return this.left + this.right;
-	}
-	
-	/// equal to top + bottom
-	T vertical() const @safe nothrow @property {
-		return this.top + this.bottom;
-	}	
-}

+ 24 - 0
source/three/renderTarget.d

@@ -0,0 +1,24 @@
+module three.renderTarget;
+
+import three.common;
+
+struct RenderTarget {
+	uint width;
+	uint height;
+	GLuint textureTarget;
+}
+
+void construct(out RenderTarget renderTarget, uint width, uint height) nothrow {
+	renderTarget.width = width;
+	renderTarget.height = height;
+	glCheck!glGenTextures(1, &renderTarget.textureTarget);
+	glCheck!glBindTexture(GL_TEXTURE_2D, renderTarget.textureTarget);
+	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, width, height);
+	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
+	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void destruct(ref RenderTarget renderTarget) nothrow {
+	glCheck!glDeleteTextures(1, &renderTarget.textureTarget);
+	renderTarget = RenderTarget.init;
+}

+ 151 - 0
source/three/renderer.d

@@ -0,0 +1,151 @@
+module three.renderer;
+
+import three.common;
+import three.scene;
+import three.camera;
+import three.renderTarget;
+import three.viewport;
+
+
+
+struct GBuffer {
+	uint width;
+	uint height;
+	GLuint textureDepth;
+	GLuint textureNormal;
+	GLuint textureColor;
+	GLuint textureDepthStencil;
+	GLuint fbo;
+}
+
+void construct(out GBuffer gBuffer, uint width, uint height) nothrow {
+	gBuffer.width = width;
+	gBuffer.width = height;
+	
+	glCheck!glGenTextures(1, &gBuffer.textureDepth);		
+	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureDepth);
+	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+	//	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
+	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, width, height);
+	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, null);	
+	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
+	
+	glCheck!glGenTextures(1, &gBuffer.textureNormal);
+	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureNormal);
+	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	glCheck!glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	
+	//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+	//	glCheck!glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB10_A2, width, height);
+	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
+	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
+	
+	glCheck!glGenTextures(1, &gBuffer.textureColor);
+	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureColor);
+	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
+	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, null);	
+	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
+	
+	glCheck!glGenTextures(1, &gBuffer.textureDepthStencil);
+	glCheck!glBindTexture(GL_TEXTURE_2D, gBuffer.textureDepthStencil);
+	glCheck!glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, width, height);
+	glCheck!glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, null);	
+	glCheck!glBindTexture(GL_TEXTURE_2D, 0);
+	
+	glCheck!glGenFramebuffers(1, &gBuffer.fbo);
+	glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gBuffer.fbo);
+	
+	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, GL_TEXTURE_2D, gBuffer.textureDepth, 0);
+	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 1, GL_TEXTURE_2D, gBuffer.textureNormal, 0);
+	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 2, GL_TEXTURE_2D, gBuffer.textureColor, 0);
+	glCheck!glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, gBuffer.textureDepthStencil, 0);
+	
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+}
+
+void destruct(ref GBuffer gBuffer) nothrow {
+	glCheck!glDeleteFramebuffers(1, &gBuffer.fbo);
+	glCheck!glDeleteTextures(1, &gBuffer.textureDepthStencil);
+	glCheck!glDeleteTextures(1, &gBuffer.textureColor);
+	glCheck!glDeleteTextures(1, &gBuffer.textureNormal);
+	glCheck!glDeleteTextures(1, &gBuffer.textureDepth);
+	gBuffer = GBuffer.init;
+}
+
+struct Pipeline {
+	GLuint pipeline;
+	GLuint vertexShaderGeometryPass;
+	GLuint fragmentShaderGeometryPass;
+}
+
+void construct(out Pipeline pipeline) nothrow {
+	glGenProgramPipelines(1, &pipeline.pipeline); 
+}
+
+void destruct(ref Pipeline pipeline) nothrow {
+	glDeleteProgramPipelines(1, &pipeline.pipeline);
+	pipeline = Pipeline.init;
+}
+
+
+struct OpenGlTiledDeferredRenderer {
+	GBuffer gBuffer;
+	Pipeline pipeline;
+}
+
+void construct(out OpenGlTiledDeferredRenderer deferredRenderer, uint width, uint height) nothrow {
+	deferredRenderer.gBuffer.construct(width, height);
+}
+
+void destruct(ref OpenGlTiledDeferredRenderer deferredRenderer) nothrow {
+	deferredRenderer.gBuffer.destruct();
+	deferredRenderer = OpenGlTiledDeferredRenderer.init;
+}
+
+// draw the scene supersampled with renderer's with+height onto renderTarget at position+size of viewport
+void renderOneFrame(ref OpenGlTiledDeferredRenderer renderer, ref Scene scene, ref Camera camera, ref RenderTarget renderTarget, ref Viewport viewport) nothrow {
+	// 1. Render the (opaque) geometry into the G-Buffers.	
+	// 2. Construct a screen space grid, covering the frame buffer, with some fixed tile
+	//    size, t = (x, y), e.g. 32 × 32 pixels.	
+	// 3. For each light: find the screen space extents of the light volume and append the
+	//    light ID to each affected grid cell.	
+	// 4. For each fragment in the frame buffer, with location f = (x, y).
+	//    (a) sample the G-Buffers at f.
+	//    (b) accumulate light contributions from all lights in tile at ⌊f /t⌋
+	//    (c) output total light contributions to frame buffer at f
+	
+	
+	with(renderer.gBuffer) glCheck!glViewport(0, 0, width, height);
+	
+	//enable depth mask _before_ glClear ing the depth buffer!
+	glCheck!glDepthMask(GL_TRUE); scope(exit) glCheck!glDepthMask(GL_FALSE);
+	glCheck!glEnable(GL_DEPTH_TEST); scope(exit) glCheck!glDisable(GL_DEPTH_TEST);
+	glCheck!glDepthFunc(GL_LEQUAL);
+	
+	//bind gBuffer
+	glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderer.gBuffer.fbo); scope(exit) glCheck!glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
+	glCheck!glDrawBuffer(GL_COLOR_ATTACHMENT0 + 0);
+	glCheck!glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+	GLenum[] drawBuffers = [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2];
+	glCheck!glDrawBuffers(drawBuffers.length, drawBuffers.ptr);
+	glCheck!glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+	
+	//bind pipeline
+	glCheck!glBindProgramPipeline(renderer.pipeline.pipeline); scope(exit) glCheck!glBindProgramPipeline(0);
+	
+	{// Draw Geometry
+		scope(exit) glCheck!glBindVertexArray(0);
+		scope(exit) glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // TODO: GL_ELEMENT_ARRAY_BUFFER should be vao state, but bugs might make this necessary
+		
+		for(size_t meshIdx = 0; meshIdx < scene.mesh.cnt; ++meshIdx) {
+			glCheck!glBindVertexArray(scene.mesh.vao[meshIdx]); 
+			
+			glCheck!glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, scene.mesh.vboIndices[meshIdx]); // TODO: GL_ELEMENT_ARRAY_BUFFER should be vao state, but bugs might make this necessary
+			
+			glCheck!glDrawElements(GL_TRIANGLES, scene.mesh.cntIndices[meshIdx], GL_UNSIGNED_SHORT, null);
+		}
+	}
+}

+ 15 - 0
source/three/scene.d

@@ -0,0 +1,15 @@
+module three.scene;
+
+import three.common;
+import three.mesh;
+
+struct Scene {
+	SOAMesh mesh;
+}
+
+void construct(out Scene scene) pure @safe nothrow @nogc {
+}
+
+void destruct(ref Scene scene) pure @safe nothrow @nogc {
+	scene = Scene.init;
+}

+ 13 - 0
source/three/viewport.d

@@ -0,0 +1,13 @@
+module three.viewport;
+
+import three.common;
+
+struct Viewport {
+}
+
+void construct(out Viewport viewport) pure @safe nothrow @nogc {
+}
+
+void destruct(ref Viewport viewport) pure @safe nothrow @nogc {
+	viewport = Viewport.init;
+}

+ 371 - 0
source/three/window.d

@@ -0,0 +1,371 @@
+module three.window;
+
+import three.common;
+
+struct Window {
+private:
+	GLFWwindow* _glfwWindow = null;
+	uint _x, _y, _width, _height;
+	KeyAction[int] _keyStates;
+	ButtonAction[int] _buttonStates;
+
+public:							
+	void delegate(Window*, int, int) onPosition;	 
+	void delegate(Window*, int, int) onSize;	 
+	void delegate(Window*) onClose;		
+	void delegate(Window*) onRefresh;			
+	void delegate(Window*, FocusAction) onFocus;	  
+	void delegate(Window*, IconifyAction) onIconify;	
+	void delegate(Window*, bool) onCursorEnter;		
+	void delegate(Window*, int, ButtonAction) onButton;	
+	void delegate(Window*, double, double) onCursorPos; 
+	void delegate(Window*, double, double) onScroll;	
+	void delegate(Window*, Key, ScanCode, KeyAction, KeyMod) onKey;   
+	void delegate(Window*, int) onChar;
+}
+
+alias ScanCode = int;
+
+enum IconifyAction {
+	Iconified,
+	Restored
+}
+
+enum FocusAction {
+	Focused,
+	Defocused
+}
+
+enum CursorAction {
+	Entered,
+	Leaved
+}
+
+enum ButtonAction {
+	Pressed,
+	Released
+}
+
+enum KeyAction {
+	Pressed,
+	Released,
+	Repeated
+}
+
+enum KeyMod {
+	Shift = 0x0001,
+	Control = 0x0002,
+	Alt = 0x0004,
+	Super = 0x0008,
+}
+
+enum Key {
+	Unknown = -1,
+	Space = 32,
+	Apostrophe = 39,
+	Comma = 44,
+	Minus = 45,
+	Period = 46,
+	Slash = 47,
+	Key0 = 48,
+	Key1 = 49,
+	Key2 = 50,
+	Key3 = 51,
+	Key4 = 52,
+	Key5 = 53,
+	Key6 = 54,
+	Key7 = 55,
+	Key8 = 56,
+	Key9 = 57,
+	Semicolon = 59,
+	Equal = 61,
+	KeyA = 65,
+	KeyB = 66,
+	KeyC = 67,
+	KeyD = 68,
+	KeyE = 69,
+	KeyF = 70,
+	KeyG = 71,
+	KeyH = 72,
+	KeyI = 73,
+	KeyJ = 74,
+	KeyK = 75,
+	Keyl = 76,
+	KeyM = 77,
+	KeyN = 78,
+	KeyO = 79,
+	KeyP = 80,
+	KeyQ = 81,
+	KeyR = 82,
+	KeyS = 83,
+	KeyT = 84,
+	KeyU = 85,
+	KeyV = 86,
+	KeyW = 87,
+	KeyX = 88,
+	KeyY = 89,
+	KeyZ = 90,
+	LeftBracket = 91,
+	Backslash = 92,
+	RightBracket = 93,
+	GraveAccent = 96,
+	World1 = 161,
+	World2 = 162,
+	Escape = 256,
+	Enter = 257,
+	Tab = 258,
+	Backspace = 259,
+	Insert = 260,
+	Delete = 261,
+	Right = 262,
+	Left = 263,
+	Down = 264,
+	Up = 265,
+	PageUp = 266,
+	PageDown = 267,
+	Home = 268,
+	End = 269,
+	CapsLock = 280,
+	ScrollLock = 281,
+	NumLock = 282,
+	PrintScreen = 283,
+	Pause = 284,
+	F1 = 290,
+	F2 = 291,
+	F3 = 292,
+	F4 = 293,
+	F5 = 294,
+	F6 = 295,
+	F7 = 296,
+	F8 = 297,
+	F9 = 298,
+	F10 = 299,
+	F11 = 300,
+	F12 = 301,
+	F13 = 302,
+	F14 = 303,
+	F15 = 304,
+	F16 = 305,
+	F17 = 306,
+	F18 = 307,
+	F19 = 308,
+	F20 = 309,
+	F21 = 310,
+	F22 = 311,
+	F23 = 312,
+	F24 = 313,
+	F25 = 314,
+	NumBlock0 = 320,
+	NumBlock1 = 321,
+	NumBlock2 = 322,
+	NumBlock3 = 323,
+	NumBlock4 = 324,
+	NumBlock5 = 325,
+	NumBlock6 = 326,
+	NumBlock7 = 327,
+	NumBlock8 = 328,
+	NumBlock9 = 329,
+	KpDecimal = 330,
+	KpDivide = 331,
+	KpMultiply = 332,
+	KpSubtract = 333,
+	KpAdd = 334,
+	KpEnter = 335,
+	KpEqual = 336,
+	LeftShift = 340,
+	LeftControl = 341,
+	LeftAlt = 342,
+	LeftSuper = 343,
+	RightShift = 344,
+	RightControl = 345,
+	RightAlt = 346,
+	RightSuper = 347,
+	Menu = 348
+}
+
+void construct(out Window window, string title, uint width, uint height) nothrow {
+	window._x = 0;
+	window._y = 0;
+	window._width = width;
+	window._height = height;
+	
+	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
+
+	glfwDefaultWindowHints();
+	glfwWindowHint(GLFW_RED_BITS, 8);
+	glfwWindowHint(GLFW_GREEN_BITS, 8);
+	glfwWindowHint(GLFW_BLUE_BITS, 8);
+	glfwWindowHint(GLFW_ALPHA_BITS, 0);
+	glfwWindowHint(GLFW_DEPTH_BITS, 24);
+	glfwWindowHint(GLFW_STENCIL_BITS, 8);
+	import std.string : toStringz;
+	window._glfwWindow = glfwCreateWindow(width, height, title.toStringz(), null, null);
+	assert(window._glfwWindow !is null);
+	
+		glfwSetWindowUserPointer(window._glfwWindow, cast(void*)&window);
+		glfwSetWindowPosCallback(window._glfwWindow, cast(GLFWwindowposfun)&_GLFWwindowposfun);
+		glfwSetWindowSizeCallback(window._glfwWindow, cast(GLFWwindowsizefun)&_GLFWwindowsizefun);
+		glfwSetWindowCloseCallback(window._glfwWindow, cast(GLFWwindowclosefun)&_GLFWwindowclosefun);
+		glfwSetWindowRefreshCallback(window._glfwWindow, cast(GLFWwindowrefreshfun)&_GLFWwindowrefreshfun);
+		glfwSetWindowIconifyCallback(window._glfwWindow, cast(GLFWwindowiconifyfun)&_GLFWwindowiconifyfun);
+		glfwSetMouseButtonCallback(window._glfwWindow, cast(GLFWmousebuttonfun)&_GLFWmousebuttonfun);
+		glfwSetCursorPosCallback(window._glfwWindow, cast(GLFWcursorposfun)&_GLFWcursorposfun);
+		//glfwSetCursorEnterCallback(window._glfwWindow, cast(GLFWcursorenterfunfun)&_GLFWcursorenterfunfun);
+		glfwSetScrollCallback(window._glfwWindow, cast(GLFWscrollfun)&_GLFWscrollfun);
+		glfwSetKeyCallback(window._glfwWindow, cast(GLFWkeyfun)&_GLFWkeyfun);
+		glfwSetCharCallback(window._glfwWindow, cast(GLFWcharfun)&_GLFWcharfun);
+	
+	glfwMakeContextCurrent(window._glfwWindow);
+}
+
+void destruct(ref Window window) {
+//	glfwSetWindowPosCallback(window._glfwWindow, null);
+//	glfwSetWindowSizeCallback(window._glfwWindow, null);
+//	glfwSetWindowCloseCallback(window._glfwWindow, null);
+//	glfwSetWindowRefreshCallback(window._glfwWindow, null);
+//	glfwSetWindowIconifyCallback(window._glfwWindow, null);
+//	glfwSetMouseButtonCallback(window._glfwWindow, null);
+//	glfwSetCursorPosCallback(window._glfwWindow, null);
+//	//glfwSetCursorEnterCallback(this._glfwWindow, null);
+//	glfwSetScrollCallback(window._glfwWindow, null);
+//	glfwSetKeyCallback(window._glfwWindow, null);
+//	glfwSetCharCallback(window._glfwWindow, null);
+	
+	glfwDestroyWindow(window._glfwWindow);
+	
+	window = Window.init;
+}
+
+void makeAktiveRenderWindow(ref Window window) nothrow @nogc {
+	glfwMakeContextCurrent(window._glfwWindow);
+}
+
+void swapBuffers(ref Window window) nothrow @nogc {
+	glfwSwapBuffers(window._glfwWindow);
+}
+
+void pollEvents(ref Window window) nothrow @nogc {
+	glfwPollEvents();
+}
+
+@property void setTitle(ref Window window, string title) nothrow {
+	import std.string : toStringz;
+	glfwSetWindowTitle(window._glfwWindow, title.toStringz());
+}
+
+KeyAction keyState(ref Window window, int key) pure @safe nothrow {
+	try {
+		return window._keyStates.get(key, KeyAction.Released);
+	}
+	catch(Exception) {
+		return KeyAction.Released;
+	}
+}
+
+ButtonAction buttonState(ref Window window, int button) pure @safe nothrow {
+	try {
+		return window._buttonStates.get(button, ButtonAction.Released);
+	}
+	catch(Exception) {
+		return ButtonAction.Released;
+	}
+}
+
+uint x(ref Window window) {
+	return window._x;
+}
+uint y(ref Window window) {
+	return window._y;
+}
+uint width(ref Window window) {
+	return window._width;
+}
+uint height(ref Window window) {
+	return window._height;
+}
+
+
+
+private Window* _castWindow(GLFWwindow* window)
+out (result) { assert(result !is null, "glfwGetWindowUserPointer returned null"); }
+body {
+	void* user_ptr = glfwGetWindowUserPointer(window);
+	return cast(Window*)user_ptr;
+}
+
+
+private extern(C) void _GLFWwindowposfun(GLFWwindow* glfwWindow, int x, int y) {							  
+	Window* window = _castWindow(glfwWindow);
+	auto monitor = glfwGetPrimaryMonitor();
+	if(monitor is null) return;
+	auto videoMode = glfwGetVideoMode(monitor);
+	y = videoMode.height - y;
+	int w,h;
+	glfwGetWindowSize(glfwWindow, &w, &h);
+	window._x = x;
+	window._y = y;
+	window._width = w;
+	window._height = h;
+	if(window.onPosition) window.onPosition(window, x, y);
+}
+
+private extern(C) void _GLFWwindowsizefun(GLFWwindow* glfwWindow, int width, int height) {												 
+	Window* window = _castWindow(glfwWindow);
+	window._width = width;
+	window._height = height;
+	if(window.onSize) window.onSize(window, width, height);
+}
+
+private extern(C) void _GLFWwindowclosefun(GLFWwindow* glfwWindow) {				  
+	Window* window = _castWindow(glfwWindow);
+	if(window.onClose) window.onClose(window);
+}
+
+private extern(C) void _GLFWwindowrefreshfun(GLFWwindow* glfwWindow) {													 
+	Window* window = _castWindow(glfwWindow);
+	if(window.onRefresh) window.onRefresh(window);
+}
+
+private extern(C) void _GLFWwindowfocusfun(GLFWwindow* glfwWindow, int focused) {													 
+	Window* window = _castWindow(glfwWindow);
+	if(window.onFocus) window.onFocus(window, (focused == GL_TRUE) ? FocusAction.Focused : FocusAction.Defocused);
+}
+
+private extern(C) void _GLFWwindowiconifyfun(GLFWwindow* glfwWindow, int iconified) {												 
+	Window* window = _castWindow(glfwWindow);
+	if(window.onIconify) window.onIconify(window, (iconified == GL_TRUE) ? IconifyAction.Iconified : IconifyAction.Restored);
+}
+
+private extern(C) void _GLFWcursorenterfun(GLFWwindow* glfwWindow, int entered) {
+	Window* window = _castWindow(glfwWindow);
+	if(window.onCursorEnter) window.onCursorEnter(window, (entered == GL_TRUE) ? CursorAction.Entered : CursorAction.Leaved);
+}
+
+private extern(C) void _GLFWmousebuttonfun(GLFWwindow* glfwWindow, int button, int action) { 
+	Window* window = _castWindow(glfwWindow);
+	window._buttonStates[button] = (action == GLFW_PRESS) ? ButtonAction.Pressed : ButtonAction.Released;
+	if(window.onButton) window.onButton(window, button, (action == GLFW_PRESS) ? ButtonAction.Pressed : ButtonAction.Released);
+}
+
+private extern(C) void _GLFWcursorposfun(GLFWwindow* glfwWindow, double x, double y) {
+	Window* window = _castWindow(glfwWindow);
+	if(window.onCursorPos) window.onCursorPos(window, x, window._height - y);
+}
+
+private extern(C) void _GLFWscrollfun(GLFWwindow* glfwWindow, double x, double y) {	
+	Window* window = _castWindow(glfwWindow);
+	if(window.onScroll) window.onScroll(window, x, y);
+}
+
+private extern(C) void _GLFWkeyfun(GLFWwindow* glfwWindow, int key, int scancode, int action, int mods) {  
+	Window* window = _castWindow(glfwWindow);
+	window._keyStates[key] = (action == GLFW_PRESS || action == GLFW_REPEAT) ? KeyAction.Pressed : KeyAction.Released;
+	if(window.onKey) window.onKey(window, cast(Key)key, cast(ScanCode)scancode, cast(KeyAction)action, cast(KeyMod)mods);
+}
+
+private extern(C) void _GLFWcharfun(GLFWwindow* glfwWindow, uint character) { 
+	Window* window = _castWindow(glfwWindow);
+	if(window.onChar) window.onChar(window, character);
+}