1 module unecht.core.components.renderer;
2 
3 import unecht.core.component;
4 import unecht.core.components.camera;
5 import unecht.core.components.material;
6 import unecht.core.components.misc;
7 import unecht.core.defaultInspector;
8 
9 import unecht.gl.program;
10 
11 import gl3n.linalg;
12 
13 /// 
14 @UEDefaultInspector!UERenderer
15 final class UERenderer : UEComponent
16 {
17 private:
18     //@Serialize
19     UEMaterial _material;
20 
21 public:
22     mixin(UERegisterObject!());
23 
24     //@Serialize
25     UEMesh mesh;
26 
27     version(UEIncludeEditor)static UEMaterial editorMaterial;
28 
29     ///
30     @property UEMaterial material(UEMaterial _v) { setMaterial(_v); return _v; }
31     ///
32     @property UEMaterial material() { return _material; }
33 
34     ///
35     void render(UECamera _cam)
36     {
37         if(!mesh)
38             return;
39 
40         auto matScale = mat4.scaling(sceneNode.scaling.x,sceneNode.scaling.y,sceneNode.scaling.z);
41         auto matModel = mat4.translation(sceneNode.position) * sceneNode.rotation.to_matrix!(4,4) * matScale;
42         
43         auto mat = _cam.projectionLook * matModel;
44         
45         version(UEIncludeEditor)
46         {
47             auto oldMaterial=_material;
48             if(_material && editorMaterial)
49                 _material = editorMaterial;
50             scope(exit) _material=oldMaterial;
51         }
52         
53         if(_material)
54             _material.preRender();
55         scope(exit)
56         {
57             if(_material)
58                 _material.postRender();
59         }
60         
61         auto posLoc = _material.attribLocation(GLAtrribTypes.position);
62         auto normLoc = _material.attribLocation(GLAtrribTypes.normal);
63         auto colorLoc = _material.attribLocation(GLAtrribTypes.color);
64         auto uvLoc = _material.attribLocation(GLAtrribTypes.texcoord);
65 
66         _material.uniforms.setMatWorld(mat);
67         _material.uniforms.setViewDir(_cam.sceneNode.forward);
68 
69         if(!mesh.vertexArrayObject)
70             return;
71 
72         mesh.vertexArrayObject.bind();
73         scope(exit) mesh.vertexArrayObject.unbind();
74         mesh.vertexBuffer.bind(posLoc);
75         scope(exit) mesh.vertexBuffer.unbind();
76         
77         if(normLoc != -1)
78         {
79             assert(mesh.normalBuffer, "shader needs Normals but mesh does not contain any");
80             mesh.normalBuffer.bind(normLoc);
81         }
82         
83         if(uvLoc != -1)
84         {
85             assert(mesh.uvBuffer, "shader needs uvBuffer but mesh does not contain any");
86             mesh.uvBuffer.bind(uvLoc);
87         }
88         
89         if(colorLoc != -1)
90         {
91             assert(mesh.colorBuffer, "shader needs Normals but mesh does not contain any");
92             mesh.colorBuffer.bind(colorLoc);
93         }
94 
95         scope(exit)
96         {
97             if(normLoc != -1)
98                 mesh.normalBuffer.unbind();
99             
100             if(uvLoc != -1)
101                 mesh.uvBuffer.unbind();
102             
103             if(colorLoc != -1)
104                 mesh.colorBuffer.unbind();
105         }
106         
107         mesh.indexBuffer.bind(0);
108         scope(exit) mesh.indexBuffer.unbind();
109 
110         material.validate();
111         mesh.indexBuffer.renderIndexed();
112     }
113 
114     private void setMaterial(UEMaterial _v)
115     {
116         _material = _v;
117     }
118 }