1 module game_core.rendering;
2 
3 import bubel.ecs.attributes;
4 import bubel.ecs.core;
5 import bubel.ecs.std;
6 
7 import ecs_utils.gfx.texture;
8 import ecs_utils.math.vector;
9 
10 import game_core.basic;
11 
12 void registerRenderingModule(EntityManager* manager)
13 {
14     manager.registerComponent!CLocation;
15     manager.registerComponent!CScale;
16     manager.registerComponent!CRotation;
17     manager.registerComponent!CDepth;
18     manager.registerComponent!CColor;
19     manager.registerComponent!CSelected;
20     manager.registerComponent!CTexCoords;
21     manager.registerComponent!CTexCoordsIndex;
22     manager.registerComponent!CMaterialIndex;
23     manager.registerComponent!CDrawDefault;
24 
25     manager.registerSystem!DrawSystem(100);
26 }
27 
28 struct CTexCoords
29 {
30     mixin ECS.Component;
31 
32     alias value this;///use component as it value
33 
34     vec4 value;
35 }
36 
37 struct CTexCoordsIndex
38 {
39     mixin ECS.Component; 
40 
41     alias value this;
42 
43     ushort value;
44 }
45 
46 struct CMaterialIndex
47 {
48     mixin ECS.Component;
49 
50     alias value this;
51 
52     ushort value;
53 }
54 
55 struct CDrawDefault
56 {
57     mixin ECS.Component;
58 }
59 
60 struct TexCoordsManager
61 {
62     import bubel.ecs.vector;
63     import bubel.ecs.hash_map;
64 
65     __gshared TexCoordsManager* instance = null;
66 
67     static void initialize()
68     {
69         if(instance is null)instance = Mallocator.make!TexCoordsManager;
70     }
71 
72     static void destroy()
73     {
74         if(instance)Mallocator.dispose(instance);
75         instance = null;
76     }
77 
78     vec4 get(ushort index)
79     {
80         if(index > coords.length)return vec4(0,0,1,1);
81         else return coords[index];
82     }
83 
84     ushort getCoordIndex(vec4 coords)
85     {
86         ushort ret = coords_map.get(coords, ushort.max);
87         if(ret != ushort.max)
88         {
89             return ret;
90         }
91         this.coords.add(coords);
92         coords_map.add(coords, cast(ushort)(this.coords.length - 1));
93         return cast(ushort)(this.coords.length - 1);
94     }
95 
96     Vector!vec4 coords;
97     HashMap!(vec4,ushort) coords_map;
98 }
99 
100 struct DrawSystem
101 {
102     mixin ECS.System!32;
103 
104     import ecs_utils.gfx.renderer : Renderer;
105 
106     struct EntitiesData
107     {
108         uint length;
109         //uint thread_id;
110         uint job_id;
111         const(Entity)[] entity;
112         @readonly CLocation[] locations;
113         @readonly @optional CScale[] scale;
114         // @readonly CTexCoords[] texcoord;
115         @readonly @optional CTexCoords[] texcoord;
116         @readonly @optional CTexCoordsIndex[] texcoord_index;
117         @readonly @optional CRotation[] rotation;
118         @readonly @optional CDepth[] depth;
119         @readonly @optional CColor[] color;
120         @readonly @optional CMaterialIndex[] material;
121         @readonly @optional CDrawDefault[] draw_default;
122     }
123 
124     Renderer.DrawData default_data;
125     float color_time = 0;
126     uint select_color = 0;
127 
128     bool onBegin()
129     {
130         import app : launcher;
131         color_time += launcher.delta_time * 0.001;
132         color_time = color_time - cast(int)(color_time*0.5)*2;
133         float ratio = color_time - cast(int)color_time;
134         if(color_time > 1)ratio = 1 - ratio;
135         uint multipler = cast(uint)(0x60 * ratio);
136         select_color = 0xA0A0A0A0 + cast(uint)(0x01010101 * multipler);
137         return true;
138     }
139 
140     void onUpdate(EntitiesData data)
141     {
142         import app : launcher;
143 
144         if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
145         Renderer.DrawData draw_data = default_data;
146         draw_data.thread_id = data.job_id;
147         
148         if(launcher.show_filtered && launcher.filterEntity(data.entity[0]))
149         {
150             draw_data.color = select_color;
151             data.color = null;
152         }
153         //import std.stdio;
154         //writeln(data.draw_default);
155         //if(data.draw_default is null && data.texcoord is null && data.texcoord_index is null && !data.entity[0].hasComponent(CDrawDefault.component_id))return;
156         
157         if(data.texcoord is null && data.texcoord_index is null && data.draw_default is null)return;
158 
159 
160         foreach(i; 0..data.length)
161         {
162             draw_data.position = data.locations[i];
163             if(data.color)draw_data.color = data.color[i];
164             if(data.depth)draw_data.depth = data.depth[i];
165             if(data.rotation)draw_data.angle = data.rotation[i];
166             if(data.scale)draw_data.size = data.scale[i];
167             if(data.texcoord)draw_data.coords = data.texcoord[i];
168             else if(data.texcoord_index)draw_data.coords = TexCoordsManager.instance.get(data.texcoord_index[i]);
169             if(data.material)draw_data.material_id = data.material[i];
170             launcher.renderer.draw(draw_data);
171         }//*/
172 
173         /*
174         ubyte mode;
175         if(data.scale)mode |= 0x01;
176         if(data.texcoord)mode |= 0x02;
177         if(data.texcoord_index)mode |= 0x04;
178         if(data.rotation)mode |= 0x08;
179         if(data.depth)mode |= 0x10;
180         if(data.color)mode |= 0x20;
181 
182         if(launcher.show_filtered && launcher.filterEntity(data.entity[0]))
183         {
184             draw_data.color = select_color;
185             mode &= ~0x20;
186             //goto draw_nocolor;
187         }
188         
189         switch(mode)
190         {
191             case 0:
192                 foreach(i; 0..data.length)
193                 {
194                     draw_data.position = data.locations[i];
195                     launcher.renderer.draw(draw_data);
196                 }
197                 break;
198 
199             case 0b000001:
200                 foreach(i; 0..data.length)
201                 {
202                     draw_data.position = data.locations[i];
203                     draw_data.size = data.scale[i];
204                     launcher.renderer.draw(draw_data);
205                 }
206                 break;
207 
208             case 0b000010:
209                 foreach(i; 0..data.length)
210                 {
211                     draw_data.position = data.locations[i];
212                     draw_data.coords = data.texcoord[i];
213                     launcher.renderer.draw(draw_data);
214                 }
215                 break;
216             case 0b000011:
217                 foreach(i; 0..data.length)
218                 {
219                     draw_data.position = data.locations[i];
220                     draw_data.size = data.scale[i];
221                     draw_data.coords = data.texcoord[i];
222                     launcher.renderer.draw(draw_data);
223                 }
224                 break;
225 
226             case 0b001000:
227                 foreach(i; 0..data.length)
228                 {
229                     draw_data.position = data.locations[i];
230                     draw_data.angle = data.rotation[i];
231                     launcher.renderer.draw(draw_data);
232                 }
233                 break;
234             case 0b001001:
235                 foreach(i; 0..data.length)
236                 {
237                     draw_data.position = data.locations[i];
238                     draw_data.angle = data.rotation[i];
239                     draw_data.size = data.scale[i];
240                     launcher.renderer.draw(draw_data);
241                 }
242                 break;
243             case 0b001010:
244                 foreach(i; 0..data.length)
245                 {
246                     draw_data.position = data.locations[i];
247                     draw_data.angle = data.rotation[i];
248                     draw_data.coords = data.texcoord[i];
249                     launcher.renderer.draw(draw_data);
250                 }
251                 break;
252             case 0b001011:
253                 foreach(i; 0..data.length)
254                 {
255                     draw_data.position = data.locations[i];
256                     draw_data.angle = data.rotation[i];
257                     draw_data.size = data.scale[i];
258                     draw_data.coords = data.texcoord[i];
259                     launcher.renderer.draw(draw_data);
260                 }
261                 break;
262 
263             
264             case 0b010000:
265                 foreach(i; 0..data.length)
266                 {
267                     draw_data.position = data.locations[i];
268                     draw_data.depth = data.depth[i];
269                     launcher.renderer.draw(draw_data);
270                 }
271                 break;
272             case 0b010001:
273                 foreach(i; 0..data.length)
274                 {
275                     draw_data.position = data.locations[i];
276                     draw_data.depth = data.depth[i];
277                     draw_data.size = data.scale[i];
278                     launcher.renderer.draw(draw_data);
279                 }
280                 break;
281             case 0b010010:
282                 foreach(i; 0..data.length)
283                 {
284                     draw_data.position = data.locations[i];
285                     draw_data.depth = data.depth[i];
286                     draw_data.coords = data.texcoord[i];
287                     launcher.renderer.draw(draw_data);
288                 }
289                 break;
290             case 0b010011:
291                 foreach(i; 0..data.length)
292                 {
293                     draw_data.position = data.locations[i];
294                     draw_data.depth = data.depth[i];
295                     draw_data.size = data.scale[i];
296                     draw_data.coords = data.texcoord[i];
297                     launcher.renderer.draw(draw_data);
298                 }
299                 break;
300             case 0b011000:
301                 foreach(i; 0..data.length)
302                 {
303                     draw_data.position = data.locations[i];
304                     draw_data.depth = data.depth[i];
305                     draw_data.angle = data.rotation[i];
306                     launcher.renderer.draw(draw_data);
307                 }
308                 break;
309             case 0b011001:
310                 foreach(i; 0..data.length)
311                 {
312                     draw_data.position = data.locations[i];
313                     draw_data.depth = data.depth[i];
314                     draw_data.angle = data.rotation[i];
315                     draw_data.size = data.scale[i];
316                     launcher.renderer.draw(draw_data);
317                 }
318                 break;
319             case 0b011010:
320                 foreach(i; 0..data.length)
321                 {
322                     draw_data.position = data.locations[i];
323                     draw_data.depth = data.depth[i];
324                     draw_data.angle = data.rotation[i];
325                     draw_data.coords = data.texcoord[i];
326                     launcher.renderer.draw(draw_data);
327                 }
328                 break;
329             case 0b011011:
330                 foreach(i; 0..data.length)
331                 {
332                     draw_data.position = data.locations[i];
333                     draw_data.depth = data.depth[i];
334                     draw_data.angle = data.rotation[i];
335                     draw_data.size = data.scale[i];
336                     draw_data.coords = data.texcoord[i];
337                     launcher.renderer.draw(draw_data);
338                 }
339                 break;
340 
341             
342             case 0b100000:
343                 foreach(i; 0..data.length)
344                 {
345                     draw_data.position = data.locations[i];
346                     draw_data.color = data.color[i];
347                     launcher.renderer.draw(draw_data);
348                 }
349                 break;
350             case 0b100001:
351                 foreach(i; 0..data.length)
352                 {
353                     draw_data.position = data.locations[i];
354                     draw_data.color = data.color[i];
355                     draw_data.size = data.scale[i];
356                     launcher.renderer.draw(draw_data);
357                 }
358                 break;
359             case 0b100010:
360                 foreach(i; 0..data.length)
361                 {
362                     draw_data.position = data.locations[i];
363                     draw_data.color = data.color[i];
364                     draw_data.coords = data.texcoord[i];
365                     launcher.renderer.draw(draw_data);
366                 }
367                 break;
368             case 0b100011:
369                 foreach(i; 0..data.length)
370                 {
371                     draw_data.position = data.locations[i];
372                     draw_data.color = data.color[i];
373                     draw_data.size = data.scale[i];
374                     draw_data.coords = data.texcoord[i];
375                     launcher.renderer.draw(draw_data);
376                 }
377                 break;
378             case 0b101000:
379                 foreach(i; 0..data.length)
380                 {
381                     draw_data.position = data.locations[i];
382                     draw_data.color = data.color[i];
383                     draw_data.angle = data.rotation[i];
384                     launcher.renderer.draw(draw_data);
385                 }
386                 break;
387             case 0b101001:
388                 foreach(i; 0..data.length)
389                 {
390                     draw_data.position = data.locations[i];
391                     draw_data.color = data.color[i];
392                     draw_data.angle = data.rotation[i];
393                     draw_data.size = data.scale[i];
394                     launcher.renderer.draw(draw_data);
395                 }
396                 break;
397             case 0b101010:
398                 foreach(i; 0..data.length)
399                 {
400                     draw_data.position = data.locations[i];
401                     draw_data.color = data.color[i];
402                     draw_data.angle = data.rotation[i];
403                     draw_data.coords = data.texcoord[i];
404                     launcher.renderer.draw(draw_data);
405                 }
406                 break;
407             case 0b101011:
408                 foreach(i; 0..data.length)
409                 {
410                     draw_data.position = data.locations[i];
411                     draw_data.color = data.color[i];
412                     draw_data.angle = data.rotation[i];
413                     draw_data.size = data.scale[i];
414                     draw_data.coords = data.texcoord[i];
415                     launcher.renderer.draw(draw_data);
416                 }
417                 break;
418             case 0b110000:
419                 foreach(i; 0..data.length)
420                 {
421                     draw_data.position = data.locations[i];
422                     draw_data.color = data.color[i];
423                     draw_data.depth = data.depth[i];
424                     launcher.renderer.draw(draw_data);
425                 }
426                 break;
427             case 0b110001:
428                 foreach(i; 0..data.length)
429                 {
430                     draw_data.position = data.locations[i];
431                     draw_data.color = data.color[i];
432                     draw_data.depth = data.depth[i];
433                     draw_data.size = data.scale[i];
434                     launcher.renderer.draw(draw_data);
435                 }
436                 break;
437             case 0b110010:
438                 foreach(i; 0..data.length)
439                 {
440                     draw_data.position = data.locations[i];
441                     draw_data.color = data.color[i];
442                     draw_data.depth = data.depth[i];
443                     draw_data.coords = data.texcoord[i];
444                     launcher.renderer.draw(draw_data);
445                 }
446                 break;
447             case 0b110011:
448                 foreach(i; 0..data.length)
449                 {
450                     draw_data.position = data.locations[i];
451                     draw_data.color = data.color[i];
452                     draw_data.depth = data.depth[i];
453                     draw_data.size = data.scale[i];
454                     draw_data.coords = data.texcoord[i];
455                     launcher.renderer.draw(draw_data);
456                 }
457                 break;
458             case 0b111000:
459                 foreach(i; 0..data.length)
460                 {
461                     draw_data.position = data.locations[i];
462                     draw_data.color = data.color[i];
463                     draw_data.depth = data.depth[i];
464                     draw_data.angle = data.rotation[i];
465                     launcher.renderer.draw(draw_data);
466                 }
467                 break;
468             case 0b111001:
469                 foreach(i; 0..data.length)
470                 {
471                     draw_data.position = data.locations[i];
472                     draw_data.color = data.color[i];
473                     draw_data.depth = data.depth[i];
474                     draw_data.angle = data.rotation[i];
475                     draw_data.size = data.scale[i];
476                     launcher.renderer.draw(draw_data);
477                 }
478                 break;
479             case 0b111010:
480                 foreach(i; 0..data.length)
481                 {
482                     draw_data.position = data.locations[i];
483                     draw_data.color = data.color[i];
484                     draw_data.depth = data.depth[i];
485                     draw_data.angle = data.rotation[i];
486                     draw_data.coords = data.texcoord[i];
487                     launcher.renderer.draw(draw_data);
488                 }
489                 break;
490             case 0b111011:
491                 foreach(i; 0..data.length)
492                 {
493                     draw_data.position = data.locations[i];
494                     draw_data.color = data.color[i];
495                     draw_data.depth = data.depth[i];
496                     draw_data.angle = data.rotation[i];
497                     draw_data.size = data.scale[i];
498                     draw_data.coords = data.texcoord[i];
499                     launcher.renderer.draw(draw_data);
500                 }
501                 break;
502             default:break;
503         }//*/
504 /*
505         if(!data.color)
506         {
507         draw_nocolor:
508             if(!data.depth)
509             {
510                 if(!data.rotation)
511                 {
512                     foreach(i; 0..data.length)
513                     {
514                         draw_data.coords = data.texcoord[i];
515                         draw_data.size = data.scale[i];
516                         draw_data.position = data.locations[i];
517                         launcher.renderer.draw(draw_data);
518                     }
519                 }
520                 else
521                 {
522                     foreach(i; 0..data.length)
523                     {
524                         draw_data.angle = data.rotation[i];
525                         draw_data.coords = data.texcoord[i];
526                         draw_data.size = data.scale[i];
527                         draw_data.position = data.locations[i];
528                         launcher.renderer.draw(draw_data);
529                     }
530                 }
531             }
532             else
533             {
534                 if(!data.rotation)
535                 {
536                     foreach(i; 0..data.length)
537                     {
538                         draw_data.depth = data.depth[i];
539                         draw_data.coords = data.texcoord[i];
540                         draw_data.size = data.scale[i];
541                         draw_data.position = data.locations[i];
542                         launcher.renderer.draw(draw_data);
543                     }
544                 }
545                 else
546                 {
547                     foreach(i; 0..data.length)
548                     {
549                         draw_data.depth = data.depth[i];
550                         draw_data.angle = data.rotation[i];
551                         draw_data.coords = data.texcoord[i];
552                         draw_data.size = data.scale[i];
553                         draw_data.position = data.locations[i];
554                         launcher.renderer.draw(draw_data);
555                     }
556                 }
557             }
558         }
559         else
560         {
561             if(!data.depth)
562             {
563                 if(!data.rotation)
564                 {
565                     foreach(i; 0..data.length)
566                     {
567                         draw_data.color = data.color[i];
568                         draw_data.coords = data.texcoord[i];
569                         draw_data.size = data.scale[i];
570                         draw_data.position = data.locations[i];
571                         launcher.renderer.draw(draw_data);
572                     }
573                 }
574                 else
575                 {
576                     foreach(i; 0..data.length)
577                     {
578                         draw_data.color = data.color[i];
579                         draw_data.angle = data.rotation[i];
580                         draw_data.coords = data.texcoord[i];
581                         draw_data.size = data.scale[i];
582                         draw_data.position = data.locations[i];
583                         launcher.renderer.draw(draw_data);
584                     }
585                 }
586             }
587             else
588             {
589                 if(!data.rotation)
590                 {
591                     foreach(i; 0..data.length)
592                     {
593                         draw_data.depth = data.depth[i];
594                         draw_data.color = data.color[i];
595                         draw_data.coords = data.texcoord[i];
596                         draw_data.size = data.scale[i];
597                         draw_data.position = data.locations[i];
598                         launcher.renderer.draw(draw_data);
599                     }
600                 }
601                 else
602                 {
603                     foreach(i; 0..data.length)
604                     {
605                         draw_data.depth = data.depth[i];
606                         draw_data.color = data.color[i];
607                         draw_data.coords = data.texcoord[i];
608                         draw_data.size = data.scale[i];
609                         draw_data.position = data.locations[i];
610                         launcher.renderer.draw(draw_data);
611                     }
612                 }
613             }
614         }*/
615     }
616 }