1 /**
2  * Copyright:   Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:     $(Gabriel Gheorghe)
4  * License:     $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:      $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/graphics/material.d, _material.d)
6  * Documentation:
7  * Coverage:
8  */
9 module liberty.graphics.material;
10 import liberty.core.engine;
11 import liberty.core.scenegraph.scene;
12 import liberty.core.imaging;
13 import liberty.graphics;
14 import liberty.core.utils : Singleton, IService;
15 import derelict.opengl;
16 import std.conv : to;
17 ///
18 final class Material {
19 	private {
20 		ShaderProgram _shader;
21 		uint _textureID;
22 		Bitmap _texture;
23 	}
24 	///
25 	this() {
26 		_shader = RenderUtil.get.createShaderProgram(vertexCode, fragmentCode);
27 		Scene.shaderList[_shader.programID.to!string] = _shader;
28 		glGenTextures(1, &_textureID);
29         _texture = new Bitmap(CoreEngine.get.imageAPI, "res/brick.bmp");
30         glBindTexture(GL_TEXTURE_2D, _textureID);
31         if (_texture.data()) {
32             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, _texture.width(), _texture.height(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, _texture.data());
33             glGenerateMipmap(GL_TEXTURE_2D);
34             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
35             glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -0.7f);
36         } else {
37             assert(0);
38         }
39         _shader.start();
40         _shader.loadUniform("fragTexture", 0);
41 	}
42 	~this() {
43 		_shader.destroy();
44 	}
45 	///
46 	ShaderProgram shader() pure nothrow @safe @nogc @property {
47 		return _shader;
48 	}
49 	///
50 	uint textureId() pure nothrow const @safe @nogc @property {
51 		return _textureID;
52 	}
53 	///
54 	void render() {
55 		_shader.loadUniform("projection", CoreEngine.get.activeScene.activeCamera.projection); // TODO: NOT HERE? ONLY ONCE?
56         _shader.loadUniform("view", CoreEngine.get.activeScene.activeCamera.view); // TODO: NOT HERE? ONLY ONCE?
57 	}
58 }
59 ///
60 final class Materials : Singleton!Materials {
61 	///
62 	Material defaultMaterial;
63 	///
64 	void load() {
65 		defaultMaterial = new Material();
66 	}
67 }
68 immutable vertexCode = q{
69 	#version 450 core
70 	layout (location = 0) in vec3 position;
71 	//layout (location = 1) in vec4 color;
72 	layout (location = 2) in vec2 texCoords;
73 	out vec2 pixelTexCoords;
74 	uniform mat4 model;
75 	uniform mat4 view;
76 	uniform mat4 projection;
77 	//uniform vec4 pixelColor;
78 	void main() {
79 		gl_Position = projection * view * model * vec4(position, 1.0f);
80 		pixelTexCoords = texCoords;
81 	}
82 };
83 immutable fragmentCode = q{
84 	#version 450 core
85 	out vec4 fragColor;
86 	in vec2 pixelTexCoords;
87 	uniform sampler2D fragTexture;
88 	//uniform vec4 fillColor;
89 	void main() {
90 		fragColor = texture(fragTexture, pixelTexCoords);// * fillColor * pixelColor;
91 	}
92 };