diff --git a/data/levels/cemetery/cemetery.blend b/data/levels/cemetery/cemetery.blend
new file mode 100644
index 0000000..61feb7e
Binary files /dev/null and b/data/levels/cemetery/cemetery.blend differ
diff --git a/data/levels/cemetery/cemetery.blend1 b/data/levels/cemetery/cemetery.blend1
new file mode 100644
index 0000000..9720cdc
Binary files /dev/null and b/data/levels/cemetery/cemetery.blend1 differ
diff --git a/data/levels/cemetery/cemetery.scene b/data/levels/cemetery/cemetery.scene
new file mode 100644
index 0000000..c422fe4
--- /dev/null
+++ b/data/levels/cemetery/cemetery.scene
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/levels/cemetery/cemetery.xml b/data/levels/cemetery/cemetery.xml
new file mode 100644
index 0000000..e74c6f4
--- /dev/null
+++ b/data/levels/cemetery/cemetery.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/data/levels/cemetery/cemetery_fence.blend b/data/levels/cemetery/cemetery_fence.blend
new file mode 100644
index 0000000..7add59a
Binary files /dev/null and b/data/levels/cemetery/cemetery_fence.blend differ
diff --git a/data/levels/cemetery/cemetery_fi.blend b/data/levels/cemetery/cemetery_fi.blend
new file mode 100644
index 0000000..5a75e53
Binary files /dev/null and b/data/levels/cemetery/cemetery_fi.blend differ
diff --git a/data/levels/cemetery/cemetery_fi.blend1 b/data/levels/cemetery/cemetery_fi.blend1
new file mode 100644
index 0000000..2732c38
Binary files /dev/null and b/data/levels/cemetery/cemetery_fi.blend1 differ
diff --git a/data/levels/cemetery/graveyard_fence.mtl b/data/levels/cemetery/graveyard_fence.mtl
new file mode 100644
index 0000000..952566c
--- /dev/null
+++ b/data/levels/cemetery/graveyard_fence.mtl
@@ -0,0 +1,12 @@
+# Blender 4.5.6 LTS MTL File: 'cemetery.blend'
+# www.blender.org
+
+newmtl graveyard_fence
+Ns 250.000000
+Ka 1.000000 1.000000 1.000000
+Ks 0.500000 0.500000 0.500000
+Ke 0.000000 0.000000 0.000000
+Ni 1.500000
+d 1.000000
+illum 2
+map_Kd data/textures/scenes/cemetery/graveyard_fence_albedo.png
diff --git a/data/levels/cemetery/graveyard_fence.obj b/data/levels/cemetery/graveyard_fence.obj
new file mode 100644
index 0000000..1eb121c
--- /dev/null
+++ b/data/levels/cemetery/graveyard_fence.obj
@@ -0,0 +1,697 @@
+# Blender 4.5.6 LTS
+# www.blender.org
+mtllib graveyard_fence.mtl
+o graveyard_fence
+v -0.260000 0.082582 -3.506247
+v -0.260000 0.082582 -4.706247
+v 0.260000 0.082582 -3.506247
+v 0.260000 0.082582 -4.706247
+v -0.200000 0.882582 -3.506247
+v -0.200000 0.882582 -4.706247
+v 0.200000 0.882582 -4.706247
+v 0.200000 0.882582 -3.506247
+v -0.260000 0.782582 -4.706247
+v 0.260000 0.782582 -4.706247
+v 0.260000 0.782582 -3.506247
+v -0.260000 0.782582 -3.506247
+v -0.200000 4.282582 -3.506248
+v -0.200000 4.282581 -4.706247
+v 0.200000 4.282581 -4.706247
+v 0.200000 4.282582 -3.506248
+v 0.121126 4.882582 -4.627574
+v -0.121126 4.882582 -4.627574
+v -0.121126 4.882582 -3.584922
+v 0.121126 4.882582 -3.584922
+v -0.121126 5.159583 -4.627574
+v -0.078127 5.202581 -4.584575
+v 0.078127 5.202581 -4.584575
+v 0.121126 5.159583 -4.627574
+v 0.078127 5.202582 -3.627921
+v 0.121126 5.159584 -3.584922
+v -0.121126 5.159584 -3.584922
+v -0.078127 5.202582 -3.627921
+v -0.181442 4.839308 -3.524619
+v -0.136702 4.882582 -3.569346
+v -0.136702 4.882582 -4.643149
+v -0.181442 4.839308 -4.687876
+v 0.136702 4.882582 -3.569346
+v 0.181442 4.839308 -3.524619
+v 0.136702 4.882582 -4.643149
+v 0.181442 4.839308 -4.687876
+v 0.260000 0.782583 3.093752
+v 0.260000 0.082583 3.093752
+v -0.260000 0.082583 3.093752
+v -0.260000 0.782583 3.093752
+v -0.200000 0.882583 3.093752
+v 0.200000 4.282583 3.093752
+v 0.200000 0.882583 3.093752
+v -0.200000 4.282583 3.093752
+v -0.260000 0.082583 3.093752
+v -0.260000 0.082583 4.293753
+v 0.260000 0.082583 3.093752
+v 0.260000 0.082583 4.293753
+v -0.200000 0.882583 3.093752
+v -0.200000 0.882583 4.293753
+v 0.200000 0.882583 4.293753
+v 0.200000 0.882583 3.093752
+v -0.260000 0.782583 4.293753
+v 0.260000 0.782583 4.293753
+v 0.260000 0.782583 3.093752
+v -0.260000 0.782583 3.093752
+v -0.200000 4.282583 3.093752
+v -0.200000 4.282583 4.293753
+v 0.200000 4.282583 4.293753
+v 0.200000 4.282583 3.093752
+v 0.121126 4.882584 4.215078
+v -0.121126 4.882584 4.215078
+v -0.121126 4.882583 3.172426
+v 0.121126 4.882583 3.172426
+v -0.121126 5.159585 4.215078
+v -0.078127 5.202583 4.172079
+v 0.078127 5.202583 4.172079
+v 0.121126 5.159585 4.215078
+v 0.078127 5.202583 3.215425
+v 0.121126 5.159585 3.172426
+v -0.121126 5.159585 3.172426
+v -0.078127 5.202583 3.215425
+v -0.181442 4.839309 3.112123
+v -0.136702 4.882583 3.156851
+v -0.136702 4.882584 4.230653
+v -0.181442 4.839310 4.275381
+v 0.136702 4.882583 3.156851
+v 0.181442 4.839309 3.112123
+v 0.136702 4.882584 4.230653
+v 0.181442 4.839310 4.275381
+v 0.200000 1.016323 -4.572505
+v 0.200000 4.148840 -4.572506
+v 0.200000 4.148840 -3.639989
+v 0.200000 1.016323 -3.639989
+v -0.200000 1.016323 -3.639989
+v -0.200000 4.148840 -3.639989
+v -0.200000 4.148840 -4.572506
+v -0.200000 1.016323 -4.572505
+v -0.200000 4.148840 -3.372505
+v -0.200000 1.016323 -3.372505
+v -0.200000 1.016325 2.960011
+v -0.200000 4.148841 2.960010
+v 0.200000 1.016323 -3.372505
+v 0.200000 4.148840 -3.372505
+v 0.200000 4.148841 2.960010
+v 0.200000 1.016325 2.960011
+v 0.200000 1.016325 4.160012
+v 0.200000 1.016325 3.227495
+v 0.200000 4.148841 3.227495
+v 0.200000 4.148842 4.160011
+v -0.200000 1.016325 3.227495
+v -0.200000 1.016325 4.160012
+v -0.200000 4.148842 4.160011
+v -0.200000 4.148841 3.227495
+v 0.144298 4.148841 3.227495
+v 0.144298 1.016325 3.227495
+v -0.144298 1.016325 3.227495
+v -0.144298 4.148841 3.227495
+v 0.144298 4.148840 -4.572506
+v 0.144298 1.016323 -4.572505
+v 0.144298 1.016323 -3.639989
+v 0.144298 4.148840 -3.639989
+v -0.144298 1.016323 -3.639989
+v -0.144298 4.148840 -3.639989
+v -0.144298 1.016323 -4.572505
+v -0.144298 4.148840 -4.572506
+v -0.144298 1.016323 -3.372505
+v -0.144298 4.148840 -3.372505
+v -0.144298 4.148841 2.960010
+v -0.144298 1.016325 2.960011
+v 0.144298 4.148840 -3.372505
+v 0.144298 1.016323 -3.372505
+v 0.144298 1.016325 2.960011
+v 0.144298 4.148841 2.960010
+v 0.144298 1.016325 4.160012
+v 0.144298 4.148842 4.160011
+v -0.144298 1.016325 4.160012
+v -0.144298 4.148842 4.160011
+vn -0.0000 -1.0000 -0.0000
+vn -0.8575 0.5145 -0.0000
+vn 0.8575 0.5145 -0.0000
+vn -0.0000 -0.0000 -1.0000
+vn -1.0000 -0.0000 -0.0000
+vn 1.0000 -0.0000 -0.0000
+vn -0.0000 1.0000 -0.0000
+vn -0.0000 -0.0000 1.0000
+vn -0.0000 0.7071 -0.7071
+vn 0.7071 0.7071 -0.0000
+vn -0.7071 0.7071 -0.0000
+vn -0.0000 0.7071 0.7071
+vn -0.6952 0.7188 -0.0000
+vn -0.0000 0.7187 -0.6953
+vn 0.6952 0.7188 -0.0000
+vn -0.0000 0.7187 0.6953
+vn -0.0000 0.0330 0.9995
+vn -0.9994 0.0333 -0.0000
+vn -0.0000 0.0330 -0.9995
+vn 0.9994 0.0333 -0.0000
+vt 0.932558 0.571789
+vt 0.970677 0.483822
+vt 0.970677 0.571789
+vt 0.652212 0.087968
+vt 0.644609 0.571789
+vt 0.644609 0.087968
+vt 0.300504 0.571789
+vt 0.292901 0.483822
+vt 0.300504 0.483822
+vt 0.491890 0.861845
+vt 0.525611 0.869176
+vt 0.487492 0.869176
+vt 0.652212 0.000000
+vt 0.703416 0.000000
+vt 0.703416 0.087968
+vt 0.525611 0.920489
+vt 0.487492 0.920489
+vt 0.351708 0.483822
+vt 0.351708 0.571789
+vt 0.703416 0.571789
+vt 0.652212 0.571789
+vt 0.970677 0.483822
+vt 1.000000 0.000000
+vt 1.000000 0.483822
+vt 0.635255 0.886694
+vt 0.631172 0.657063
+vt 0.635255 0.657063
+vt 0.491890 0.612607
+vt 0.521213 0.861845
+vt 0.626350 0.766240
+vt 0.622266 0.697881
+vt 0.626350 0.697881
+vt 0.669659 0.724655
+vt 0.655053 0.727823
+vt 0.658205 0.724655
+vt 0.655053 0.645070
+vt 0.658404 0.571789
+vt 0.658404 0.648222
+vt 0.655053 0.651374
+vt 0.658404 0.724655
+vt 0.655053 0.721503
+vt 0.669659 0.748129
+vt 0.655053 0.751294
+vt 0.658205 0.748129
+vt 0.655053 0.748129
+vt 0.672812 0.727823
+vt 0.672812 0.748129
+vt 0.563730 0.770702
+vt 0.575185 0.700573
+vt 0.575185 0.770702
+vt 0.678667 0.724655
+vt 0.678667 0.648222
+vt 0.678667 0.571789
+vt 0.655053 0.771599
+vt 0.672812 0.751294
+vt 0.672812 0.771599
+vt 0.351708 0.004626
+vt 0.355088 0.086621
+vt 0.351708 0.083342
+vt 0.651773 0.653784
+vt 0.628451 0.657063
+vt 0.631731 0.653784
+vt 0.000000 0.567164
+vt 0.003380 0.485168
+vt 0.003380 0.570442
+vt 0.631731 0.575068
+vt 0.655053 0.571789
+vt 0.651773 0.575068
+vt 0.563730 0.700573
+vt 0.591692 0.659757
+vt 0.593053 0.700573
+vt 0.395901 -0.000000
+vt 0.395901 0.087968
+vt 0.632873 0.576210
+vt 0.632873 0.652643
+vt 0.519852 0.571789
+vt 0.521213 0.612607
+vt 0.650631 0.652643
+vt 0.650631 0.576210
+vt 0.044193 0.483822
+vt 0.044193 0.571789
+vt 0.530009 0.821028
+vt 0.563730 0.828359
+vt 0.525611 0.828359
+vt 0.563730 0.879673
+vt 0.525611 0.879673
+vt 0.530009 0.571789
+vt 0.559332 0.821028
+vt 0.351708 0.000000
+vt 0.597136 0.659757
+vt 0.601219 0.889387
+vt 0.597136 0.889387
+vt 0.635255 0.657063
+vt 0.639339 0.886694
+vt 0.635255 0.886694
+vt 0.300504 0.000000
+vt 0.932558 0.483822
+vt 0.970677 0.000000
+vt 0.601850 0.659757
+vt 0.563730 0.571789
+vt 0.601850 0.571789
+vt 0.000000 0.872293
+vt 0.087968 0.864690
+vt 0.087968 0.872293
+vt 0.449373 0.869176
+vt 0.483093 0.861845
+vt 0.487492 0.869176
+vt 0.175935 0.872293
+vt 0.175935 0.864690
+vt 0.087968 0.923497
+vt 0.175935 0.923497
+vt 0.449373 0.920490
+vt 0.487492 0.920490
+vt 0.643422 0.886694
+vt 0.639339 0.657063
+vt 0.643422 0.657063
+vt 0.453771 0.861845
+vt 0.483093 0.612606
+vt 0.698737 0.793014
+vt 0.694653 0.724655
+vt 0.698737 0.724655
+vt 0.690570 0.751294
+vt 0.675964 0.748129
+vt 0.687418 0.748129
+vt 0.682018 0.648222
+vt 0.678667 0.721503
+vt 0.678667 0.651374
+vt 0.678667 0.574941
+vt 0.678667 0.645070
+vt 0.690570 0.727823
+vt 0.675964 0.724655
+vt 0.687418 0.724655
+vt 0.690570 0.771599
+vt 0.586639 0.770702
+vt 0.575185 0.700573
+vt 0.586639 0.700573
+vt 0.702281 0.571789
+vt 0.702281 0.648222
+vt 0.682018 0.724655
+vt 0.702281 0.724655
+vt 0.690570 0.748129
+vt 0.174588 0.575169
+vt 0.092593 0.571789
+vt 0.171310 0.571789
+vt 0.605129 0.575068
+vt 0.628451 0.571789
+vt 0.625172 0.575068
+vt 0.083342 0.571789
+vt 0.001347 0.575169
+vt 0.004626 0.571789
+vt 0.625172 0.653784
+vt 0.601850 0.657063
+vt 0.605129 0.653784
+vt 0.601850 0.697881
+vt 0.629812 0.657063
+vt 0.631172 0.697881
+vt 0.087968 0.615982
+vt 0.175935 0.615982
+vt 0.606271 0.652643
+vt 0.606271 0.576210
+vt 0.453771 0.612606
+vt 0.481733 0.571789
+vt 0.624030 0.576210
+vt 0.624030 0.652643
+vt 0.000000 0.615982
+vt 0.086621 0.575169
+vt 0.283118 0.561985
+vt 0.292901 0.571789
+vt 0.053976 0.493626
+vt 0.053976 0.561985
+vt 0.283118 0.493626
+vt 0.405684 0.078163
+vt 0.634826 0.078163
+vt 0.644609 0.000000
+vt 0.405684 0.009804
+vt 0.634826 0.009804
+vt 0.405684 0.097772
+vt 0.634826 0.097772
+vt 0.395901 0.571789
+vt 0.634826 0.561985
+vt 0.405684 0.561985
+vt 0.283118 0.474017
+vt 0.044193 -0.000000
+vt 0.053976 0.474017
+vt 0.292901 0.000000
+vt 0.053976 0.009804
+vt 0.283118 0.009804
+vt 0.009804 0.854907
+vt 0.078164 0.854907
+vt 0.000000 0.864690
+vt 0.009804 0.625765
+vt 0.078164 0.625765
+vt 0.166131 0.854907
+vt 0.097772 0.854907
+vt 0.166131 0.625765
+vt 0.097772 0.625765
+vt 0.175935 0.571789
+vt 0.244295 0.800931
+vt 0.175935 0.800931
+vt 0.312654 0.571789
+vt 0.312654 0.800931
+vt 0.932558 0.000000
+vt 0.703416 0.464213
+vt 0.703416 0.000000
+vt 0.703416 0.928427
+vt 0.932558 0.464213
+vt 0.932558 0.928427
+vt 0.381013 0.800931
+vt 0.381013 0.571789
+vt 0.449373 0.571789
+vt 0.449373 0.800931
+vt 0.626349 0.697881
+vt 0.630433 0.766240
+vt 0.626349 0.766240
+vt 0.643422 0.657063
+vt 0.647505 0.886694
+vt 0.586639 0.700573
+vt 0.590722 0.768933
+vt 0.586639 0.768933
+vt 0.974761 0.948035
+vt 0.974761 0.483822
+vt 0.702820 0.793014
+vt 0.698737 0.724655
+vt 0.702820 0.724655
+vt 0.694653 0.793014
+vt 0.690570 0.724655
+vt 0.978844 0.948035
+vt 0.974761 0.483822
+vt 0.978844 0.483822
+vt 0.622266 0.766240
+vt 0.626349 0.834600
+vt 0.622266 0.834600
+vt 0.605933 0.927511
+vt 0.601850 0.697881
+vt 0.605933 0.697881
+vt 0.647505 0.657063
+vt 0.651589 0.886694
+vt 0.647505 0.886694
+vt 0.982927 0.948035
+vt 0.610016 0.927511
+vt 0.610016 0.697881
+vt 0.597136 0.889388
+vt 0.593053 0.659757
+vt 0.597136 0.659757
+vt 0.982927 0.483822
+vt 0.987011 0.948035
+vt 0.982927 0.948035
+vt 0.610016 0.697881
+vt 0.614099 0.927511
+vt 0.610016 0.927511
+vt 0.614100 0.697881
+vt 0.618183 0.927511
+vt 0.614100 0.927511
+vt 0.626349 0.766240
+vt 0.630433 0.834600
+vt 0.622266 0.927511
+vt 0.618183 0.697881
+vt 0.622266 0.697881
+vt 0.970677 0.000000
+vt 0.631172 0.886694
+vt 0.622266 0.766240
+vt 0.655053 0.574941
+vt 0.563730 0.700573
+vt 0.355088 0.001347
+vt 0.655053 0.657063
+vt 0.000000 0.488447
+vt 0.628451 0.571789
+vt 0.565091 0.659757
+vt 0.493251 0.571789
+vt 0.559332 0.571789
+vt 0.601219 0.659757
+vt 0.639339 0.657063
+vt 0.932558 0.000000
+vt 0.563730 0.659757
+vt 0.000000 0.923497
+vt 0.639339 0.886694
+vt 0.694653 0.793014
+vt 0.682018 0.571789
+vt 0.089314 0.575169
+vt 0.628451 0.657063
+vt 0.603210 0.657063
+vt 0.455131 0.571789
+vt 0.244295 0.571789
+vt 0.932558 0.464213
+vt 0.703416 0.464213
+vt 0.630433 0.697881
+vt 0.647505 0.657063
+vt 0.590722 0.700573
+vt 0.970677 0.948035
+vt 0.698737 0.793014
+vt 0.690570 0.793014
+vt 0.974761 0.948035
+vt 0.601850 0.927511
+vt 0.651589 0.657063
+vt 0.982927 0.483822
+vt 0.593053 0.889388
+vt 0.987011 0.483822
+vt 0.614099 0.697881
+vt 0.618183 0.697881
+vt 0.630433 0.766240
+vt 0.618183 0.927511
+s 1
+usemtl graveyard_fence
+f 4/1/1 1/2/1 2/3/1
+f 12/4/2 41/5/2 5/6/2
+f 10/7/3 8/8/3 11/9/3
+f 6/10/4 10/11/4 9/12/4
+f 5/6/2 9/13/2 12/4/2
+f 12/4/5 2/14/5 1/15/5
+f 9/12/4 4/16/4 2/17/4
+f 10/7/6 3/18/6 4/19/6
+f 12/4/5 39/20/5 40/21/5
+f 13/22/7 42/23/7 16/24/7
+f 90/25/8 118/26/8 89/27/8
+f 14/28/4 7/29/4 6/10/4
+f 81/30/7 111/31/7 84/32/7
+f 23/33/9 21/34/9 22/35/9
+f 23/36/10 26/37/10 24/38/10
+f 22/39/11 27/40/11 28/41/11
+f 28/42/12 26/43/12 25/44/12
+f 18/45/4 24/46/4 17/47/4
+f 22/48/7 25/49/7 23/50/7
+f 19/51/5 21/38/5 18/52/5
+f 20/53/6 24/38/6 26/37/6
+f 20/54/8 27/55/8 19/56/8
+f 31/57/13 29/58/13 30/59/13
+f 35/60/14 32/61/14 31/62/14
+f 35/63/15 34/64/15 36/65/15
+f 30/66/16 34/67/16 33/68/16
+f 16/69/17 29/70/17 13/71/17
+f 29/58/18 14/72/18 13/73/18
+f 33/68/7 19/74/7 30/66/7
+f 31/62/7 19/74/7 18/75/7
+f 14/28/19 36/76/19 15/77/19
+f 35/60/7 18/75/7 17/78/7
+f 35/60/7 20/79/7 33/68/7
+f 36/65/20 16/80/20 15/81/20
+f 43/82/8 40/83/8 37/84/8
+f 37/84/8 39/85/8 38/86/8
+f 42/87/8 41/88/8 43/82/8
+f 11/9/6 38/89/6 3/18/6
+f 86/90/4 113/91/4 85/92/4
+f 82/93/8 110/94/8 81/95/8
+f 8/8/3 37/96/3 11/9/3
+f 3/97/1 39/98/1 1/2/1
+f 45/99/1 48/100/1 46/101/1
+f 55/102/3 51/103/3 54/104/3
+f 54/105/8 50/106/8 53/107/8
+f 56/108/2 50/103/2 49/109/2
+f 46/110/5 56/108/5 45/111/5
+f 48/112/8 53/107/8 46/113/8
+f 48/110/6 55/102/6 54/104/6
+f 101/114/8 108/115/8 104/116/8
+f 51/117/8 58/118/8 50/106/8
+f 104/119/1 128/120/1 103/121/1
+f 65/122/12 67/123/12 66/124/12
+f 68/125/10 69/126/10 67/127/10
+f 72/128/11 65/125/11 66/129/11
+f 70/130/9 72/131/9 69/132/9
+f 68/55/8 62/133/8 61/56/8
+f 69/134/7 66/135/7 67/136/7
+f 65/125/5 63/137/5 62/138/5
+f 70/139/6 61/138/6 64/140/6
+f 71/46/4 64/141/4 63/47/4
+f 73/142/13 75/143/13 74/144/13
+f 75/145/16 80/146/16 79/147/16
+f 79/148/15 78/149/15 77/150/15
+f 77/151/14 73/152/14 74/153/14
+f 57/154/19 78/155/19 60/156/19
+f 58/157/18 73/142/18 57/158/18
+f 63/159/7 77/151/7 74/153/7
+f 62/160/7 74/153/7 75/145/7
+f 59/161/17 76/162/17 58/118/17
+f 61/163/7 75/145/7 79/147/7
+f 64/164/7 79/147/7 77/151/7
+f 60/165/20 80/166/20 59/157/20
+f 15/81/6 81/167/6 7/168/6
+f 15/81/6 83/169/6 82/170/6
+f 8/8/6 83/169/6 16/80/6
+f 7/168/6 84/171/6 8/8/6
+f 5/6/5 86/172/5 85/173/5
+f 14/72/5 86/172/5 13/73/5
+f 6/174/5 87/175/5 14/72/5
+f 5/6/5 88/176/5 6/174/5
+f 5/6/5 89/177/5 13/73/5
+f 41/5/5 90/178/5 5/6/5
+f 44/179/5 91/180/5 41/5/5
+f 44/179/5 89/177/5 92/181/5
+f 16/80/6 93/182/6 8/8/6
+f 42/183/6 94/184/6 16/80/6
+f 43/185/6 95/186/6 42/183/6
+f 8/8/6 96/187/6 43/185/6
+f 51/103/6 98/188/6 97/189/6
+f 60/165/6 98/188/6 52/190/6
+f 59/157/6 99/191/6 60/165/6
+f 51/103/6 100/192/6 59/157/6
+f 50/103/5 101/193/5 49/109/5
+f 58/157/5 102/194/5 50/103/5
+f 58/157/5 104/195/5 103/196/5
+f 57/158/5 101/193/5 104/195/5
+f 109/197/6 111/198/6 110/199/6
+f 113/198/5 116/200/5 115/201/5
+f 117/202/5 119/203/5 118/204/5
+f 121/205/6 123/206/6 122/207/6
+f 125/208/6 105/200/6 126/209/6
+f 127/208/5 108/210/5 107/211/5
+f 85/212/7 115/213/7 88/214/7
+f 94/215/8 122/216/8 93/114/8
+f 83/217/1 109/218/1 82/219/1
+f 89/220/1 119/2/1 92/221/1
+f 98/222/7 125/223/7 97/224/7
+f 87/225/1 114/226/1 86/120/1
+f 93/227/7 123/228/7 96/229/7
+f 102/230/7 107/231/7 101/232/7
+f 84/233/4 112/234/4 83/235/4
+f 99/236/8 106/237/8 98/238/8
+f 91/229/7 117/239/7 90/227/7
+f 97/240/4 126/235/4 100/241/4
+f 88/242/8 116/243/8 87/244/8
+f 95/245/1 121/246/1 94/247/1
+f 103/248/4 127/249/4 102/250/4
+f 92/251/4 120/252/4 91/253/4
+f 100/254/1 105/255/1 99/231/1
+f 96/256/4 124/257/4 95/258/4
+f 4/1/1 3/97/1 1/2/1
+f 12/4/2 40/21/2 41/5/2
+f 10/7/3 7/168/3 8/8/3
+f 6/10/4 7/29/4 10/11/4
+f 5/6/2 6/174/2 9/13/2
+f 12/4/5 9/13/5 2/14/5
+f 9/12/4 10/11/4 4/16/4
+f 10/7/6 11/9/6 3/18/6
+f 12/4/5 1/15/5 39/20/5
+f 13/22/7 44/259/7 42/23/7
+f 90/25/8 117/260/8 118/26/8
+f 14/28/4 15/77/4 7/29/4
+f 81/30/7 110/261/7 111/31/7
+f 23/33/9 24/46/9 21/34/9
+f 23/36/10 25/262/10 26/37/10
+f 22/39/11 21/38/11 27/40/11
+f 28/42/12 27/55/12 26/43/12
+f 18/45/4 21/34/4 24/46/4
+f 22/48/7 28/263/7 25/49/7
+f 19/51/5 27/40/5 21/38/5
+f 20/53/6 17/52/6 24/38/6
+f 20/54/8 26/43/8 27/55/8
+f 31/57/13 32/264/13 29/58/13
+f 35/60/14 36/265/14 32/61/14
+f 35/63/15 33/266/15 34/64/15
+f 30/66/16 29/267/16 34/67/16
+f 16/69/17 34/268/17 29/70/17
+f 29/58/18 32/264/18 14/72/18
+f 33/68/7 20/79/7 19/74/7
+f 31/62/7 30/66/7 19/74/7
+f 14/28/19 32/269/19 36/76/19
+f 35/60/7 31/62/7 18/75/7
+f 35/60/7 17/78/7 20/79/7
+f 36/65/20 34/64/20 16/80/20
+f 43/82/8 41/88/8 40/83/8
+f 37/84/8 40/83/8 39/85/8
+f 42/87/8 44/270/8 41/88/8
+f 11/9/6 37/96/6 38/89/6
+f 86/90/4 114/271/4 113/91/4
+f 82/93/8 109/272/8 110/94/8
+f 8/8/3 43/185/3 37/96/3
+f 3/97/1 38/273/1 39/98/1
+f 45/99/1 47/274/1 48/100/1
+f 55/102/3 52/190/3 51/103/3
+f 54/105/8 51/117/8 50/106/8
+f 56/108/2 53/104/2 50/103/2
+f 46/110/5 53/104/5 56/108/5
+f 48/112/8 54/105/8 53/107/8
+f 48/110/6 47/275/6 55/102/6
+f 101/114/8 107/276/8 108/115/8
+f 51/117/8 59/161/8 58/118/8
+f 104/119/1 108/277/1 128/120/1
+f 65/122/12 68/55/12 67/123/12
+f 68/125/10 70/139/10 69/126/10
+f 72/128/11 71/278/11 65/125/11
+f 70/130/9 71/46/9 72/131/9
+f 68/55/8 65/122/8 62/133/8
+f 69/134/7 72/50/7 66/135/7
+f 65/125/5 71/278/5 63/137/5
+f 70/139/6 68/125/6 61/138/6
+f 71/46/4 70/130/4 64/141/4
+f 73/142/13 76/279/13 75/143/13
+f 75/145/16 76/101/16 80/146/16
+f 79/148/15 80/166/15 78/149/15
+f 77/151/14 78/280/14 73/152/14
+f 57/154/19 73/281/19 78/155/19
+f 58/157/18 76/279/18 73/142/18
+f 63/159/7 64/164/7 77/151/7
+f 62/160/7 63/159/7 74/153/7
+f 59/161/17 80/282/17 76/162/17
+f 61/163/7 62/160/7 75/145/7
+f 64/164/7 61/163/7 79/147/7
+f 60/165/20 78/149/20 80/166/20
+f 15/81/6 82/170/6 81/167/6
+f 15/81/6 16/80/6 83/169/6
+f 8/8/6 84/171/6 83/169/6
+f 7/168/6 81/167/6 84/171/6
+f 5/6/5 13/73/5 86/172/5
+f 14/72/5 87/175/5 86/172/5
+f 6/174/5 88/176/5 87/175/5
+f 5/6/5 85/173/5 88/176/5
+f 5/6/5 90/178/5 89/177/5
+f 41/5/5 91/180/5 90/178/5
+f 44/179/5 92/181/5 91/180/5
+f 44/179/5 13/73/5 89/177/5
+f 16/80/6 94/184/6 93/182/6
+f 42/183/6 95/186/6 94/184/6
+f 43/185/6 96/187/6 95/186/6
+f 8/8/6 93/182/6 96/187/6
+f 51/103/6 52/190/6 98/188/6
+f 60/165/6 99/191/6 98/188/6
+f 59/157/6 100/192/6 99/191/6
+f 51/103/6 97/189/6 100/192/6
+f 50/103/5 102/194/5 101/193/5
+f 58/157/5 103/196/5 102/194/5
+f 58/157/5 57/158/5 104/195/5
+f 57/158/5 49/109/5 101/193/5
+f 109/197/6 112/283/6 111/198/6
+f 113/198/5 114/283/5 116/200/5
+f 117/202/5 120/284/5 119/203/5
+f 121/205/6 124/285/6 123/206/6
+f 125/208/6 106/201/6 105/200/6
+f 127/208/5 128/209/5 108/210/5
+f 85/212/7 113/286/7 115/213/7
+f 94/215/8 121/287/8 122/216/8
+f 83/217/1 112/288/1 109/218/1
+f 89/220/1 118/289/1 119/2/1
+f 98/222/7 106/290/7 125/223/7
+f 87/225/1 116/291/1 114/226/1
+f 93/227/7 122/292/7 123/228/7
+f 102/230/7 127/254/7 107/231/7
+f 84/233/4 111/293/4 112/234/4
+f 99/236/8 105/294/8 106/237/8
+f 91/229/7 120/295/7 117/239/7
+f 97/240/4 125/233/4 126/235/4
+f 88/242/8 115/296/8 116/243/8
+f 95/245/1 124/297/1 121/246/1
+f 103/248/4 128/298/4 127/249/4
+f 92/251/4 119/299/4 120/252/4
+f 100/254/1 126/300/1 105/255/1
+f 96/256/4 123/301/4 124/257/4
diff --git a/data/levels/cemetery/graveyard_fence_ao.png b/data/levels/cemetery/graveyard_fence_ao.png
new file mode 100644
index 0000000..a380f02
Binary files /dev/null and b/data/levels/cemetery/graveyard_fence_ao.png differ
diff --git a/data/levels/cemetery/graveyard_fence_tex.png b/data/levels/cemetery/graveyard_fence_tex.png
new file mode 100644
index 0000000..666d3e4
Binary files /dev/null and b/data/levels/cemetery/graveyard_fence_tex.png differ
diff --git a/data/shaders/lit_generic.ps b/data/shaders/lit_generic.ps
index 0bc9c70..3f0299f 100644
--- a/data/shaders/lit_generic.ps
+++ b/data/shaders/lit_generic.ps
@@ -11,7 +11,8 @@ uniform vec4 u_customColor;
void main() {
//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
//gl_FragColor = u_customColor * vec4(v_finalColor, 1.0) * texture2D(u_albedoTexture, v_texcoord);
- gl_FragColor = vec4(v_finalColor, 1.0) * texture2D(u_albedoTexture, v_texcoord);
+ //gl_FragColor = vec4(v_finalColor, 1.0) * texture2D(u_albedoTexture, v_texcoord);
+ gl_FragColor = texture2D(u_albedoTexture, v_texcoord);
//gl_FragColor = vec4( v_normal, 1.0 );
//gl_FragColor = texture2D(u_albedoTexture, v_texcoord);
}
\ No newline at end of file
diff --git a/data/textures/figures_color.png b/data/textures/figures_color.png
deleted file mode 100644
index 37c7474..0000000
Binary files a/data/textures/figures_color.png and /dev/null differ
diff --git a/data/textures/scenes/cemetery/graveyard_fence_albedo.png b/data/textures/scenes/cemetery/graveyard_fence_albedo.png
new file mode 100644
index 0000000..c045c89
Binary files /dev/null and b/data/textures/scenes/cemetery/graveyard_fence_albedo.png differ
diff --git a/engine.log b/engine.log
index 485646f..4791153 100644
--- a/engine.log
+++ b/engine.log
@@ -1,21 +1,47 @@
'engine' build 1593, Feb 13 2026
NVIDIA Corporation
-GeForce GTX 750 Ti/PCIe/SSE2
-OpenGL ver. 3.2.0 NVIDIA 457.85
+NVIDIA GeForce RTX 2060 SUPER/PCIe/SSE2
+OpenGL ver. 3.2.0 NVIDIA 566.03
Context created with OpenGL version 3.2
...found GL_ARB_debug_output
loaded notex
+created shader from file data/shaders/lit_generic.vs
+created shader from file data/shaders/lit_generic.ps
created shader from file data/shaders/debug_draw.vs
created shader from file data/shaders/debug_draw.ps
Initializing entity manager ...
-total registered 2 entities
+total registered 3 entities
actor_player
ActorBase
Player actor entity
-Loading OBJ file data/levels/test/scene.obj...
-Loading MTL file data/levels/test/scene.mtl...
-loaded wood1
-loaded walls_and_floor
-Loaded Model 'data/levels/test/scene.obj'
-created shader from file data/shaders/lit_generic.vs
-created shader from file data/shaders/lit_generic.ps
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded graveyard_fence_albedo
+loaded 14 meshes
+--- unfreed textures ---
+data/textures/notex.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
+data/textures/scenes/cemetery/graveyard_fence_albedo.png
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index ede9338..d48c213 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -73,8 +73,8 @@ void Engine::Init()
}
// Initialize renderer
- g_pRender = new Render();
- g_pRender->Init(m_window);
+ g_render = new Render();
+ g_render->Init(m_window);
// Initialize engine
@@ -100,11 +100,11 @@ void Engine::Shutdown()
g_entityManager->Shutdown();
- if (g_pRender) {
- g_pRender->Shutdown();
+ if (g_render) {
+ g_render->Shutdown();
- delete g_pRender;
- g_pRender = nullptr;
+ delete g_render;
+ g_render = nullptr;
}
if (m_window) {
@@ -209,23 +209,33 @@ void Engine::RenderFrame()
if (camera)
{
Viewport vp = { 0,0,windowSizeX,windowSizeY };
- g_pRender->SetProjectionMatrix(camera->GetProjectionMatrix(vp));
- g_pRender->SetViewMatrix(camera->GetViewMatrix());
+
+ // calculate frustum
+
+ glm::mat4 viewProj = camera->GetProjectionMatrix(vp) * camera->GetViewMatrix();
+ viewProj = glm::transpose(viewProj);
+
+ camera->GetFrustum().Build(viewProj);
+
+ // set to renderer
+
+ g_render->SetProjectionMatrix(camera->GetProjectionMatrix(vp));
+ g_render->SetViewMatrix(camera->GetViewMatrix());
}
// install viewport
- g_pRenderDevice->SetViewport(0, 0, windowSizeX, windowSizeY);
+ g_renderDevice->SetViewport(0, 0, windowSizeX, windowSizeY);
- g_pRenderDevice->Clear(TST_COLOR | TST_DEPTH, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0xffffffff);
+ g_renderDevice->Clear(TST_COLOR | TST_DEPTH, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0xffffffff);
- g_pRender->RenderScene();
+ g_render->RenderScene();
- g_pRender->RenderStats();
+ g_render->RenderStats();
// ImGui scope end ***
g_ImGuiManager.EndFrame();
- g_pRender->Present();
+ g_render->Present();
}
static bool Server_validateMap(const char* mapname)
@@ -253,7 +263,7 @@ void Engine::NewGame(const char* mapname)
g_world = new World();
- g_pRender->LoadSceneXML(mapname);
+ g_render->LoadSceneXML(mapname);
// after initializing client scene and collision system - we initialize the server game
g_game->InitForNewMap(mapname);
diff --git a/src/engine/physics/physicsdebugdraw.cpp b/src/engine/physics/physicsdebugdraw.cpp
index 1006355..c03ca93 100644
--- a/src/engine/physics/physicsdebugdraw.cpp
+++ b/src/engine/physics/physicsdebugdraw.cpp
@@ -10,7 +10,7 @@ void PhysicsDebugDraw::drawLine(const btVector3& from, const btVector3& to, cons
glm::vec3 btFrom = glm::vec3(from.x(), from.y(), from.z());
glm::vec3 btTo = glm::vec3(to.x(), to.y(), to.z());
glm::vec3 btColor = glm::vec3(color.x(), color.y(), color.z());
- g_pDebugRender->DrawLine(btFrom, btTo, btColor);
+ g_debugRender->DrawLine(btFrom, btTo, btColor);
}
void PhysicsDebugDraw::drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color)
diff --git a/src/game/game_object.cpp b/src/game/game_object.cpp
index 7fcc214..363901a 100644
--- a/src/game/game_object.cpp
+++ b/src/game/game_object.cpp
@@ -21,7 +21,7 @@ void Entity::Render()
void Entity::LoadModel(const char* filename)
{
- m_model = g_pModelSystem->LoadModel(filename);
+ m_model = g_modelSystem->LoadModel(filename);
}
REGISTER_ENTITY(TempPlayer);
@@ -109,6 +109,8 @@ uint32_t TempPlayer::GenMovementDir()
return movementDir;
}
+REGISTER_ENTITY(Weapon);
+
Weapon::Weapon()
{
}
diff --git a/src/render/debugrender.cpp b/src/render/debugrender.cpp
index 00d40b5..72ac867 100644
--- a/src/render/debugrender.cpp
+++ b/src/render/debugrender.cpp
@@ -21,7 +21,7 @@ static InputLayoutDesc_t g_debugRenderLayout[] =
bool g_drawDebug = true;
-DebugRender* g_pDebugRender;
+DebugRender* g_debugRender;
DebugRender::DebugRender()
{
@@ -38,11 +38,11 @@ DebugRender::~DebugRender()
void DebugRender::Initialize()
{
//float points[12];
- //m_verticesBuffer = g_pRenderDevice->CreateVertexBuffer(points, sizeof(points), true);
+ //m_verticesBuffer = g_renderDevice->CreateVertexBuffer(points, sizeof(points), true);
- m_verticesBuffer = g_pRenderDevice->CreateVertexBuffer(NULL, kMaxDebugVBSize, true);
+ m_verticesBuffer = g_renderDevice->CreateVertexBuffer(NULL, kMaxDebugVBSize, true);
- m_shader = g_pShaderSystem->CreateShader("debug_draw",
+ m_shader = g_shaderSystem->CreateShader("debug_draw",
"data/shaders/debug_draw.vs",
"data/shaders/debug_draw.ps",
g_debugRenderLayout,
@@ -120,26 +120,26 @@ void DebugRender::DrawLinesInternal()
if (m_lines.empty())
return;
- g_pRenderDevice->SetDepthTest(true);
- g_pRenderDevice->SetDepthWrite(true);
+ g_renderDevice->SetDepthTest(true);
+ g_renderDevice->SetDepthWrite(true);
- g_pRenderDevice->SetVerticesBuffer(m_verticesBuffer);
+ g_renderDevice->SetVerticesBuffer(m_verticesBuffer);
m_verticesBuffer->UpdateBuffer(m_lines.data(), m_lines.size() * sizeof(Line));
// Bind our shader
- g_pShaderSystem->SetShader(m_shader);
+ g_shaderSystem->SetShader(m_shader);
// #TODO: Fix stupid bug, when we get very far from wireframe and lines can start cliping
- glm::mat4 proj = g_pRender->GetProjectionMatrix();
- glm::mat4 view = g_pRender->GetViewMatrix();
+ glm::mat4 proj = g_render->GetProjectionMatrix();
+ glm::mat4 view = g_render->GetViewMatrix();
proj[2][3] -= 0.0001f;
glm::mat4 mv = glm::mat4(1.0f);
mv = proj * view;
- g_pShaderSystem->SetUniformMatrix(m_shader, UNIFORM_MVP_MATRIX, &mv[0]);
+ g_shaderSystem->SetUniformMatrix(m_shader, UNIFORM_MVP_MATRIX, &mv[0]);
// draw stuff
- g_pRenderDevice->DrawArrays(PT_LINES, 0, m_lines.size() * 2);
+ g_renderDevice->DrawArrays(PT_LINES, 0, m_lines.size() * 2);
}
diff --git a/src/render/debugrender.h b/src/render/debugrender.h
index e4978ff..e794457 100644
--- a/src/render/debugrender.h
+++ b/src/render/debugrender.h
@@ -48,7 +48,7 @@ private:
Shader* m_shader;
};
-extern DebugRender* g_pDebugRender;
+extern DebugRender* g_debugRender;
extern bool g_drawDebug;
diff --git a/src/render/imguimanager.cpp b/src/render/imguimanager.cpp
index 278edb5..498d8c1 100644
--- a/src/render/imguimanager.cpp
+++ b/src/render/imguimanager.cpp
@@ -17,7 +17,7 @@ void ImGuiManager::Init()
// Initialize backend
- ImGui_ImplSDL3_InitForOpenGL(GetEngine()->GetWindow(), g_pRender->GetGLContext());
+ ImGui_ImplSDL3_InitForOpenGL(GetEngine()->GetWindow(), g_render->GetGLContext());
ImGui_ImplOpenGL3_Init();
diff --git a/src/render/modelsystem.cpp b/src/render/modelsystem.cpp
index 643d10b..98237a2 100644
--- a/src/render/modelsystem.cpp
+++ b/src/render/modelsystem.cpp
@@ -11,7 +11,7 @@
#include "modelsystem.h"
#include "texturesmanager.h"
-ModelSystem* g_pModelSystem = nullptr;
+ModelSystem* g_modelSystem = nullptr;
static InputLayoutDesc_t g_staticVertexLayout[] = {
{ VERTEXATTR_VEC3, SHADERSEMANTIC_POSITION },
@@ -45,6 +45,13 @@ ModelSystem::~ModelSystem()
{
}
+void ModelSystem::Init()
+{
+ // Load model generic shader
+ g_litShader = g_shaderSystem->CreateShader("lit_generic", "data/shaders/lit_generic.vs", "data/shaders/lit_generic.ps",
+ g_staticVertexLayout, sizeof(g_staticVertexLayout) / sizeof(g_staticVertexLayout[0]));
+}
+
void ModelSystem::Shutdown()
{
for (int i = 0; i < m_models.size(); i++)
@@ -255,7 +262,7 @@ void Model::LoadObj(const char* filename)
m_Vertices = vertices;
- m_data.vb = g_pRenderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
+ m_data.vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
m_data.vbcount = vertices.size();
std::string mtlfilename = getFileNameWithoutExtension(filename);
@@ -286,7 +293,7 @@ void Model::LoadMtl(const char* filename)
fgets(stupidBuffer, 1000, file);
const char* textureFilename = stupidBuffer + 1;
- m_AlbedoTexture = g_pTexturesManager->LoadTexture2D(textureFilename, true);
+ m_AlbedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true);
}
//if (strcmp(lineHeader, "v") == 0) {
@@ -307,40 +314,36 @@ void Model::LoadMtl(const char* filename)
void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/)
{
- if (!g_litShader)
- {
- g_litShader = g_pShaderSystem->CreateShader("lit_generic", "data/shaders/lit_generic.vs", "data/shaders/lit_generic.ps",
- g_staticVertexLayout, sizeof(g_staticVertexLayout) / sizeof(g_staticVertexLayout[0]));
- }
+ SDL_assert(g_litShader);
glFrontFace(GL_CCW);
glDepthFunc(GL_LESS);
- g_pRenderDevice->SetCullFace(true);
- g_pRenderDevice->SetDepthTest(true);
- g_pRenderDevice->SetDepthWrite(true);
+ g_renderDevice->SetCullFace(true);
+ g_renderDevice->SetDepthTest(true);
+ g_renderDevice->SetDepthWrite(true);
if (isTransparent)
{
// Enable blending
- g_pRenderDevice->SetBlending(true);
- g_pRenderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
+ g_renderDevice->SetBlending(true);
+ g_renderDevice->SetBlendingFunction(BF_SRC_ALPHA, BF_ONE_MINUS_SRC_ALPHA);
glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, .5f);
- g_pShaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
+ g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
else
{
- g_pRenderDevice->SetBlending(false);
+ g_renderDevice->SetBlending(false);
//glm::vec4 color = glm::vec4(1.f, 1.f, 1.f, 1.f);
- //g_pShaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
+ //g_shaderSystem->SetUniformFloat4(g_litShader, UNIFORM_CUSTOM_COLOR, glm::value_ptr(color));
}
- g_pRenderDevice->SetVerticesBuffer(m_data.vb);
+ g_renderDevice->SetVerticesBuffer(m_data.vb);
- g_pShaderSystem->SetShader(g_litShader);
- g_pShaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]);
+ g_shaderSystem->SetShader(g_litShader);
+ g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &model[0]);
//static float test = 0.0f;
//test += g_systemTimer->GetDelta() * 6.0f;
@@ -367,27 +370,27 @@ void Model::Draw(const glm::mat4& model, bool isTransparent /*= false*/)
//model = glm::translate(model, pos);
glm::mat4 mvp = glm::identity();
- mvp = g_pRender->GetProjectionMatrix() * g_pRender->GetViewMatrix() * model;
- g_pShaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
+ mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix() * model;
+ g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
- g_pTexturesManager->SetTexture(0, m_AlbedoTexture);
- g_pShaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
+ g_texturesManager->SetTexture(0, m_AlbedoTexture);
+ g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
- g_pRenderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
+ g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
#if 0
glm::mat4 mvp = glm::identity();
mvp = g_renderView.proj * g_renderView.view * model;
g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
- g_pTexturesManager->SetTexture(0, m_AlbedoTexture);
+ g_texturesManager->SetTexture(0, m_AlbedoTexture);
g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_data.vbcount);
BoundingBox bbox = m_boundingBox;
TransformBoundingBox(bbox, model);
- g_pDebugRender->DrawBoundingBox(bbox, glm::vec3(1.0f));
+ g_debugRender->DrawBoundingBox(bbox, glm::vec3(1.0f));
#endif
}
diff --git a/src/render/modelsystem.h b/src/render/modelsystem.h
index 4b35af9..9cdc8c7 100644
--- a/src/render/modelsystem.h
+++ b/src/render/modelsystem.h
@@ -51,6 +51,7 @@ public:
ModelSystem();
~ModelSystem();
+ void Init();
void Shutdown();
Model* LoadModel(const char* filename);
@@ -66,6 +67,6 @@ private:
};
-extern ModelSystem* g_pModelSystem;
+extern ModelSystem* g_modelSystem;
#endif // !MODELMANAGER_H
diff --git a/src/render/render.cpp b/src/render/render.cpp
index 66f9ee6..ba189f8 100644
--- a/src/render/render.cpp
+++ b/src/render/render.cpp
@@ -9,8 +9,7 @@
#include "ifilesystem.h"
#include "camera.h"
#include "imguimanager.h"
-
-#include
+#include "scenemanager.h"
static GLuint g_VAO = 0;
@@ -66,17 +65,16 @@ void APIENTRY GL_DebugOutput(GLenum source,
}
}
-Render* g_pRender = nullptr;
+Render* g_render = nullptr;
Render::Render() :
m_pWindow(nullptr),
m_pGLContext(nullptr),
m_pStretchedPicVBuf(nullptr),
- m_sceneModel(nullptr),
- m_bUsingVAO(false)
+ m_usingVAO(false)
{
- m_ViewMatrix = glm::identity();
- m_ProjectionMatrix = glm::identity();
+ m_viewMatrix = glm::identity();
+ m_projectionMatrix = glm::identity();
}
Render::~Render()
@@ -101,7 +99,7 @@ void Render::Init(SDL_Window* pWindow)
// Core profile probably, should use VAO
if (GLVersion.major >= 3 && GLVersion.minor >= 1)
- m_bUsingVAO = true;
+ m_usingVAO = true;
Msg("%s", (const char*)glGetString(GL_VENDOR));
Msg("%s", (const char*)glGetString(GL_RENDERER));
@@ -126,31 +124,35 @@ void Render::Init(SDL_Window* pWindow)
// Create render device
- g_pRenderDevice = new RenderDevice();
+ g_renderDevice = new RenderDevice();
// Create texture manager
- g_pTexturesManager = new TexturesManager();
- g_pTexturesManager->Init();
+ g_texturesManager = new TexturesManager();
+ g_texturesManager->Init();
// Create shader system
- g_pShaderSystem = new ShaderSystem();
- g_pShaderSystem->Init();
+ g_shaderSystem = new ShaderSystem();
+ g_shaderSystem->Init();
// Create model system
- g_pModelSystem = new ModelSystem();
+ g_modelSystem = new ModelSystem();
+ g_modelSystem->Init();
+
+ // Create scene manager
+ g_sceneManager = new SceneManager();
// Create debug render
- g_pDebugRender = new DebugRender();
- g_pDebugRender->Initialize();
+ g_debugRender = new DebugRender();
+ g_debugRender->Initialize();
// Create imgui manager
g_ImGuiManager.Init();
// Create stretched picture filenameBuffer
- m_pStretchedPicVBuf = g_pRenderDevice->CreateVertexBuffer(nullptr, MAX_STRETCH_VX, true);
+ m_pStretchedPicVBuf = g_renderDevice->CreateVertexBuffer(nullptr, MAX_STRETCH_VX, true);
// Core profile require Vertex Array Object to render
- if (m_bUsingVAO)
+ if (m_usingVAO)
{
// Create global vertex array
glGenVertexArrays(1, &g_VAO);
@@ -160,7 +162,7 @@ void Render::Init(SDL_Window* pWindow)
void Render::Shutdown()
{
- if (m_bUsingVAO)
+ if (m_usingVAO)
{
glBindVertexArray(0);
glDeleteVertexArrays(1, &g_VAO);
@@ -171,24 +173,27 @@ void Render::Shutdown()
g_ImGuiManager.Shutdown();
- g_pDebugRender->Shutdown();
- delete g_pDebugRender;
- g_pDebugRender = nullptr;
+ g_debugRender->Shutdown();
+ delete g_debugRender;
+ g_debugRender = nullptr;
- g_pModelSystem->Shutdown();
- delete g_pModelSystem;
- g_pModelSystem = nullptr;
+ delete g_sceneManager;
+ g_sceneManager = nullptr;
- g_pShaderSystem->Shutdown();
- delete g_pShaderSystem;
- g_pShaderSystem = nullptr;
+ g_modelSystem->Shutdown();
+ delete g_modelSystem;
+ g_modelSystem = nullptr;
- g_pTexturesManager->Shutdown();
- delete g_pTexturesManager;
- g_pTexturesManager = nullptr;
+ g_shaderSystem->Shutdown();
+ delete g_shaderSystem;
+ g_shaderSystem = nullptr;
- delete g_pRenderDevice;
- g_pRenderDevice = nullptr;
+ g_texturesManager->Shutdown();
+ delete g_texturesManager;
+ g_texturesManager = nullptr;
+
+ delete g_renderDevice;
+ g_renderDevice = nullptr;
// Destroy OpenGL context
SDL_GL_MakeCurrent(nullptr, nullptr);
@@ -197,35 +202,40 @@ void Render::Shutdown()
}
void Render::RenderScene() {
- if (m_sceneModel) {
- Camera* camera = g_cameraManager.GetActiveCamera();
- if (camera) {
- glm::mat4 viewProj = m_ProjectionMatrix * m_ViewMatrix;
- viewProj = glm::transpose(viewProj);
+ //if (m_sceneModel) {
+ // Camera* camera = g_cameraManager.GetActiveCamera();
+ // if (camera) {
+ // glm::mat4 viewProj = m_projectionMatrix * m_viewMatrix;
+ // viewProj = glm::transpose(viewProj);
- camera->GetFrustum().Build(viewProj);
+ // camera->GetFrustum().Build(viewProj);
- if (camera->GetFrustum().CullBoundingBox(m_sceneModel->GetBoundingBox()))
- return;
- }
+ // if (camera->GetFrustum().CullBoundingBox(m_sceneModel->GetBoundingBox()))
+ // return;
+ // }
- static glm::mat4 s_identity = glm::mat4(1.0f);
- m_sceneModel->Draw(s_identity);
+ // static glm::mat4 s_identity = glm::mat4(1.0f);
+ // m_sceneModel->Draw(s_identity);
- g_NumModels++;
-
- g_pDebugRender->DrawBoundingBox(m_sceneModel->GetBoundingBox(), glm::vec3(1.0f));
- }
+ // g_NumModels++;
+ //
+ // g_debugRender->DrawBoundingBox(m_sceneModel->GetBoundingBox(), glm::vec3(1.0f));
+ //}
- g_pDebugRender->RenderFrame();
+ static glm::mat4 s_identity = glm::mat4(1.0f);
+ if (g_sceneManager->isSceneLoaded())
+ g_sceneManager->renderScene(s_identity);
+
+ g_debugRender->RenderFrame();
}
void Render::RenderStats()
{
char buffer[256];
- snprintf(buffer, sizeof(buffer), "Scene: %s", m_sceneName.c_str());
+ snprintf(buffer, sizeof(buffer), "Scene: %s", g_sceneManager->getSceneName());
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 0.0f), 0xffffffff, buffer);
+
snprintf(buffer, sizeof(buffer), "numModels: %d", g_NumModels);
ImGui::GetForegroundDrawList()->AddText(ImVec2(0.0f, 15.0f), 0xffffffff, buffer);
}
@@ -240,65 +250,30 @@ void Render::Present(bool vsync)
void Render::ResetStates()
{
- g_pRenderDevice->SetDepthTest(true);
- g_pRenderDevice->SetDepthWrite(true);
- g_pRenderDevice->SetStencilTest(false);
- g_pRenderDevice->SetScissorTest(false);
- g_pRenderDevice->SetCullFace(false);
- g_pRenderDevice->SetBlending(false);
+ g_renderDevice->SetDepthTest(true);
+ g_renderDevice->SetDepthWrite(true);
+ g_renderDevice->SetStencilTest(false);
+ g_renderDevice->SetScissorTest(false);
+ g_renderDevice->SetCullFace(false);
+ g_renderDevice->SetBlending(false);
}
void Render::SetViewMatrix(const glm::mat4& matView)
{
- m_ViewMatrix = matView;
+ m_viewMatrix = matView;
}
void Render::SetProjectionMatrix(const glm::mat4& matProjection)
{
- m_ProjectionMatrix = matProjection;
+ m_projectionMatrix = matProjection;
}
void Render::LoadSceneXML(const char* filename)
{
- char filenameBuffer[kMaxPathLength];
- snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
-
- FileHandle_t file = GetFileSystem()->OpenFile(filenameBuffer, "rb");
- SDL_assert_always(file != kInvalidFileHandleValue);
-
- size_t length = GetFileSystem()->GetFileLength(file);
-
- char* filedata = new char[length + 1];
- GetFileSystem()->ReadFile(file, filedata, length);
- filedata[length] = '\0';
-
- GetFileSystem()->CloseFile(file);
-
- pugi::xml_document doc;
- pugi::xml_parse_result result = doc.load_buffer(filedata, length);
- delete[] filedata;
- if (!result) {
- Core::Error("SceneManager::LoadScene: Error while reading level description file '%s'\nError: %s:%i",
- filenameBuffer, result.description(), result.offset);
- }
-
- pugi::xml_node root = doc.document_element();
- const char* scenefilename = root.child("SceneFile").attribute("filename").value();
-
- m_sceneName = scenefilename;
-
- sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename);
-
- if (!GetFileSystem()->IsExist(filenameBuffer)) {
- Core::Error("SceneManager::LoadScene: scene file '%s' doesnt exist", scenefilename);
- }
-
- m_sceneFilename = filenameBuffer;
-
- m_sceneModel = g_pModelSystem->LoadModel(m_sceneFilename.c_str());
+ g_sceneManager->loadScene(filename);
}
//IRender* GetRender()
//{
-// return g_pRender;
+// return g_render;
//}
\ No newline at end of file
diff --git a/src/render/render.h b/src/render/render.h
index b16db1d..4932196 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -28,31 +28,26 @@ public:
void SetViewMatrix(const glm::mat4& matView);
void SetProjectionMatrix(const glm::mat4& matProjection);
- inline const glm::mat4& GetViewMatrix() { return m_ViewMatrix; }
- inline const glm::mat4& GetProjectionMatrix() { return m_ProjectionMatrix; }
+ inline const glm::mat4& GetViewMatrix() { return m_viewMatrix; }
+ inline const glm::mat4& GetProjectionMatrix() { return m_projectionMatrix; }
void LoadSceneXML(const char* filename);
SDL_GLContext GetGLContext() { return m_pGLContext; }
private:
- glm::mat4 m_ViewMatrix;
- glm::mat4 m_ProjectionMatrix;
+ glm::mat4 m_viewMatrix;
+ glm::mat4 m_projectionMatrix;
SDL_Window* m_pWindow;
SDL_GLContext m_pGLContext;
GPUBuffer* m_pStretchedPicVBuf;
- std::string m_sceneFilename;
- std::string m_sceneName;
-
- Model* m_sceneModel;
-
- bool m_bUsingVAO;
+ bool m_usingVAO;
};
-extern Render* g_pRender;
+extern Render* g_render;
// TEMP
extern glm::vec3 g_viewOrigin;
diff --git a/src/render/renderdevice.cpp b/src/render/renderdevice.cpp
index 5b6bc05..6539d0c 100644
--- a/src/render/renderdevice.cpp
+++ b/src/render/renderdevice.cpp
@@ -14,7 +14,7 @@ static GLenum g_glPrimitiveMode[PT_TRIANGLES + 1] = {
};
// The render device instance.
-RenderDevice* g_pRenderDevice = nullptr;
+RenderDevice* g_renderDevice = nullptr;
RenderDevice::RenderDevice()
{
diff --git a/src/render/renderdevice.h b/src/render/renderdevice.h
index 03ebee9..fbe33b0 100644
--- a/src/render/renderdevice.h
+++ b/src/render/renderdevice.h
@@ -54,6 +54,6 @@ private:
BlendFactor m_destBlendFactor;
};
-extern RenderDevice* g_pRenderDevice;
+extern RenderDevice* g_renderDevice;
#endif // !RENDERDEVICE_H
diff --git a/src/render/scenemanager.cpp b/src/render/scenemanager.cpp
new file mode 100644
index 0000000..0ae8c49
--- /dev/null
+++ b/src/render/scenemanager.cpp
@@ -0,0 +1,676 @@
+#include "engine/core.h"
+#include "engine/log.h"
+#include "engine/ifilesystem.h"
+#include "engine/camera.h"
+#include "render/texturesmanager.h"
+#include "render/modelsystem.h"
+#include "render/scenemanager.h"
+#include "render/renderdevice.h"
+#include "render/gl_shared.h"
+#include "render/texture2d.h"
+#include "render/shader.h"
+#include "render/shadersystem.h"
+#include "render/render.h"
+#include "render/debugrender.h"
+
+#include
+
+static std::string getFileExtension(const std::string& filename)
+{
+ size_t whereIsDot = filename.find_last_of('.');
+ if (whereIsDot != std::string::npos) {
+ return filename.substr(whereIsDot);
+ }
+
+ return "";
+}
+
+static std::string getFileNameWithoutExtension(const std::string& filename)
+{
+ size_t lastindex = filename.find_last_of(".");
+ if (lastindex != std::string::npos) {
+ return filename.substr(0, lastindex);
+ }
+
+ return filename;
+}
+
+static std::string getFilenameWithoutPathAndExtension(const std::string& filename)
+{
+ size_t whereIsDot = filename.find_last_of('.');
+ size_t whereIsSlash = filename.find_last_of('/');
+ if (whereIsSlash == std::string::npos) {
+ whereIsSlash = filename.find_last_of('\\');
+ }
+
+ if (whereIsDot == std::string::npos && whereIsSlash == std::string::npos) {
+ return filename;
+ }
+
+ std::string string = filename.substr(whereIsSlash + 1);
+ whereIsDot = string.find_last_of('.');
+ string = string.substr(0, whereIsDot);
+
+ return string;
+}
+
+//#ifdef NDEBUG
+//#pragma comment(lib, "assimp-vc141-mt.lib")
+//#else
+//#pragma comment(lib, "assimp-vc141-mtd.lib")
+//#endif // NDEBUG
+//
+//inline static glm::mat4 Assimp2Glm(const aiMatrix4x4& from)
+//{
+// return glm::mat4(
+// (double)from.a1, (double)from.b1, (double)from.c1, (double)from.d1,
+// (double)from.a2, (double)from.b2, (double)from.c2, (double)from.d2,
+// (double)from.a3, (double)from.b3, (double)from.c3, (double)from.d3,
+// (double)from.a4, (double)from.b4, (double)from.c4, (double)from.d4
+// );
+//}
+//
+//SceneStaticMesh* createSceneStaticMesh(const aiScene* scene, aiMesh* mesh)
+//{
+// assert(scene);
+// assert(mesh);
+// //assert(mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE);
+//
+// std::vector vertices;
+// std::vector indices;
+//
+// // reserve 1024 vertices and indices
+// vertices.reserve(1024);
+// indices.reserve(1024);
+//
+// for (uint32_t i = 0; i < mesh->mNumVertices; i++) {
+// SceneStaticMeshVertex vertex;
+//
+// // position
+// aiVector3D position = mesh->mVertices[i];
+// vertex.m_position.x = position.x;
+// vertex.m_position.y = position.y;
+// vertex.m_position.z = position.z;
+//
+// // normal
+// aiVector3D normal = mesh->mNormals[i];
+// vertex.m_normal.x = normal.x;
+// vertex.m_normal.y = normal.y;
+// vertex.m_normal.z = normal.z;
+//
+// static bool inverseTexCoords = true;
+//
+// if (inverseTexCoords) {
+// // texture coord 0 ( DIFFUSE )
+// if (mesh->mTextureCoords[0]) {
+// vertex.m_texcoord1.x = mesh->mTextureCoords[0][i].x;
+// vertex.m_texcoord1.y = mesh->mTextureCoords[0][i].y;
+// }
+// else {
+// vertex.m_texcoord1 = glm::vec2(0.0f, 0.0f);
+// }
+//
+// // texture coord 1 ( LIGHTMAP )
+// if (mesh->mTextureCoords[1]) {
+// vertex.m_texcoord0.x = mesh->mTextureCoords[1][i].x;
+// vertex.m_texcoord0.y = mesh->mTextureCoords[1][i].y;
+// }
+// else {
+// vertex.m_texcoord0 = glm::vec2(0.0f, 0.0f);
+// }
+// }
+// else {
+// // texture coord 0 ( DIFFUSE )
+// if (mesh->mTextureCoords[0]) {
+// vertex.m_texcoord0.x = mesh->mTextureCoords[0][i].x;
+// vertex.m_texcoord0.y = mesh->mTextureCoords[0][i].y;
+// }
+// else {
+// vertex.m_texcoord0 = glm::vec2(0.0f, 0.0f);
+// }
+//
+// // texture coord 0 ( LIGHTMAP )
+// if (mesh->mTextureCoords[1]) {
+// vertex.m_texcoord1.x = mesh->mTextureCoords[1][i].x;
+// vertex.m_texcoord1.y = mesh->mTextureCoords[1][i].y;
+// }
+// else {
+// vertex.m_texcoord1 = glm::vec2(0.0f, 0.0f);
+// }
+// }
+//
+// vertices.push_back(vertex);
+// }
+//
+// for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
+// aiFace face = mesh->mFaces[i];
+// for (uint32_t j = 0; j < face.mNumIndices; j++)
+// indices.push_back(face.mIndices[j]);
+// }
+//
+// aiMaterial* assImpMaterial = scene->mMaterials[mesh->mMaterialIndex];
+// aiString diffusePath;
+// assImpMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &diffusePath);
+//
+// if (strlen(diffusePath.C_Str()) == 0) {
+// Logger::msg("Scene mesh '%s' has assImpMaterial, but diffuse texture is not specified.", mesh->mName.C_Str());
+// }
+//
+// Material* material = g_materialsManager->createMaterial("default_lightmap", diffusePath.C_Str());
+//
+// glm::mat4 transform = glm::identity();
+//
+// return new SceneStaticMesh(vertices, indices, material, transform);
+//}
+
+SceneManager* g_sceneManager;
+
+SceneManager::SceneManager()
+{
+ m_sceneLoaded = false;
+}
+
+SceneManager::~SceneManager()
+{
+ m_sceneLoaded = false;
+}
+
+void SceneManager::loadScene(const char* filename)
+{
+ char filenameBuffer[kMaxPathLength];
+ snprintf(filenameBuffer, kMaxPathLength, "data/levels/%s/%s.xml", filename, filename);
+
+ FileHandle_t file = GetFileSystem()->OpenFile(filenameBuffer, "rb");
+ SDL_assert_always(file != kInvalidFileHandleValue);
+
+ size_t length = GetFileSystem()->GetFileLength(file);
+
+ char* filedata = new char[length + 1];
+ GetFileSystem()->ReadFile(file, filedata, length);
+ filedata[length] = '\0';
+
+ GetFileSystem()->CloseFile(file);
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_buffer(filedata, length);
+ delete[] filedata;
+ if (!result) {
+ Core::Error("SceneManager::LoadScene: Error while reading level description file '%s'\nError: %s:%i",
+ filenameBuffer, result.description(), result.offset);
+ }
+
+ pugi::xml_node root = doc.document_element();
+ const char* scenefilename = root.child("SceneFile").attribute("filename").value();
+
+ m_sceneName = getFileNameWithoutExtension(scenefilename);
+
+ sprintf(filenameBuffer, "data/levels/%s/%s", filename, scenefilename);
+
+ if (!GetFileSystem()->IsExist(filenameBuffer)) {
+ Core::Error("SceneManager::LoadScene: scene file '%s' doesnt exist", scenefilename);
+ }
+
+ m_sceneFilename = filenameBuffer;
+
+ if (getFileExtension(m_sceneFilename) == ".scene") {
+ LoadSceneXML(m_sceneFilename.c_str());
+ }
+
+ Logger::Msg("loaded %u meshes", m_sceneMeshes.size());
+
+ m_sceneLoaded = true;
+}
+
+void SceneManager::LoadSceneXML(const char* filename)
+{
+ FileHandle_t file = GetFileSystem()->OpenFile(filename, "rb");
+ SDL_assert_always(file != kInvalidFileHandleValue);
+
+ size_t length = GetFileSystem()->GetFileLength(file);
+
+ char* filedata = new char[length + 1];
+ GetFileSystem()->ReadFile(file, filedata, length);
+ filedata[length] = '\0';
+
+ GetFileSystem()->CloseFile(file);
+
+ pugi::xml_document doc;
+ pugi::xml_parse_result result = doc.load_buffer(filedata, length);
+ delete[] filedata;
+ if (!result) {
+ Core::Error("SceneManager::LoadSceneXML: Error while reading level description file '%s'\nError: %s:%i",
+ filename, result.description(), result.offset);
+ }
+
+ for (pugi::xml_node staticMesh : doc.child("Scene").children("StaticMesh")) {
+ const char* meshfilename = staticMesh.attribute("filename").as_string();
+ if (meshfilename)
+ loadStaticMesh(meshfilename);
+ }
+}
+
+//void SceneManager::loadScene(const char* sceneName)
+//{
+// if (sceneName)
+// m_sceneName = getFileNameWithoutExtension(sceneName);
+//
+// if (!m_sceneName.size())
+// Core::Error("Scene::loadScene: Scene file is empty, check the 'SceneFile' attribute in level description.");
+//
+// m_sceneFilename = "data/levels/" + std::string(sceneName) + "/" + std::string(sceneName) + ".scene.xml";
+//
+// if (!GetFileSystem()->IsExist(m_sceneFilename.c_str()))
+// Core::Error("Scene::loadScene: scene file '%s' doesnt exist", m_sceneFilename.c_str());
+//
+// Logger::Msg("loading scene %s", m_sceneFilename.c_str());
+//
+// loadStaticMeshes();
+//
+// // Load lightmap
+//// m_lightmap = g_texturesManager->createTexture2D("**");
+//
+// //if (!scene->HasTextures()) {
+// // Core::error("Scene::loadScene: scene '%s' doesnt have textures. Please check assImpMaterial parameters!", scenefilename);
+// //}
+//
+// m_sceneLoaded = true;
+//}
+
+void SceneManager::loadSkybox(const char* skybox)
+{
+ if (skybox && *skybox && strcmp(skybox, "none"))
+ m_pSkybox = g_modelSystem->LoadModel(skybox);
+}
+
+void SceneManager::loadStaticMeshes()
+{
+ //File* file = g_fileManager->openFile(m_sceneFilename.c_str(), FileAccess::Read);
+
+ //file->seek(SeekDir::End, 0);
+ //size_t length = file->tell();
+ //file->seek(SeekDir::Begin, 0);
+
+ //char* filedata = new char[length + 1];
+ //file->read(filedata, length);
+ //filedata[length] = '\0';
+
+ //g_fileManager->closeFile(file);
+
+ //Assimp::Importer importer;
+ //const aiScene* scene = importer.ReadFileFromMemory(filedata, length,
+ // aiProcessPreset_TargetRealtime_Quality | // some optimizations and safety checks
+ // aiProcess_OptimizeMeshes | // minimize number of meshes
+ // aiProcess_PreTransformVertices | // apply node matrices
+ // // aiProcess_Triangulate |
+ // aiProcess_SplitLargeMeshes |
+ // aiProcess_TransformUVCoords /*|*/ // apply UV transformations
+ ///*aiProcess_FlipUVs*/);
+
+ //delete[] filedata;
+
+ //if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
+ // Core::error("Scene::loadScene: failed to load scene '%s'.\n%s", m_sceneName, importer.GetErrorString());
+ //}
+
+ //if (scene && !scene->HasMaterials()) {
+ // Core::error("Scene::loadScene: scene '%s' doesnt have materials. Please check export parameters!", m_sceneName);
+ //}
+
+ //Logger::msg("loaded %u meshes", scene->mNumMeshes);
+ //for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
+ // m_sceneMeshes.push_back(createSceneStaticMesh(scene, scene->mMeshes[i]));
+ //}
+}
+
+void SceneManager::loadStaticMesh(const char* filename)
+{
+ char filenamebuf[kMaxPathLength];
+ snprintf(filenamebuf, kMaxPathLength, "data/levels/%s/%s", m_sceneName.c_str(), filename);
+
+ if (GetFileSystem()->IsExist(filenamebuf)) {
+ SceneStaticMesh* staticMesh = new SceneStaticMesh();
+ staticMesh->LoadObj(filenamebuf);
+ m_sceneMeshes.push_back(staticMesh);
+ }
+}
+
+bool SceneManager::isSceneLoaded()
+{
+ return m_sceneLoaded;
+}
+
+void SceneManager::renderScene(const glm::mat4& cameraTranslation)
+{
+ if (!isSceneLoaded())
+ return;
+
+ Camera* camera = g_cameraManager.GetActiveCamera();
+ if (!camera)
+ return;
+
+ Frustum& frustum = camera->GetFrustum();
+
+ for (std::list::iterator it = m_sceneMeshes.begin(); it != m_sceneMeshes.end(); ++it) {
+ if (*it) {
+ // cull mesh
+ if (frustum.CullBoundingBox((*it)->GetBoundingBox()))
+ continue;
+
+ (*it)->RenderObjects();
+
+ g_debugRender->DrawBoundingBox((*it)->GetBoundingBox(), glm::vec3(1.0f));
+ }
+ }
+
+ // draw skybox
+ //if (m_pSkybox)
+ // m_pSkybox->renderObjects(cameraTranslation);
+
+ //glActiveTexture(GL_TEXTURE1);
+ //m_lightmap->bind();
+
+ //if (g_lmTexFilter.getValueB()) {
+ // //m_lightmap->setMin
+ //}
+
+ //m_lightmap->setWrapS(TextureWrap::ClampToEdge);
+ //m_lightmap->setWrapT(TextureWrap::ClampToEdge);
+
+ //for (std::list::iterator it = m_sceneMeshes.begin(); it != m_sceneMeshes.end(); ++it) {
+ // if (*it) {
+ // (*it)->renderObjects();
+ // }
+ //}
+
+ //glActiveTexture(GL_TEXTURE1);
+ //glBindTexture(GL_TEXTURE_2D, 0);
+
+}
+
+void SceneManager::unloadIfScenePresent()
+{
+ if (!isSceneLoaded())
+ return;
+
+ unloadScene();
+}
+
+void SceneManager::replaceMaterial(const char* oldMaterialname, const char* newMaterialName)
+{
+
+}
+
+void SceneManager::replaceAllMaterialsWithBruteForce(const char* materialname)
+{
+ /*for (std::list::iterator it = m_sceneMeshes.begin();
+ it != m_sceneMeshes.end();
+ ++it)
+ {
+ SceneStaticMesh* mesh = (*it);
+ assert(mesh);
+ assert(mesh->m_material && "scene mesh has nullptr assImpMaterial");
+
+ mesh->m_material = g_materialsManager->createMaterial(materialname,
+ mesh->m_material->getTemplateMaterial()->m_diffuseTextures[0].c_str());
+ }*/
+}
+
+void SceneManager::unloadScene()
+{
+ Logger::Msg("deleting scene ...");
+
+ if (m_sceneMeshes.empty())
+ return;
+
+ for (std::list::iterator it = m_sceneMeshes.begin();
+ it != m_sceneMeshes.end();
+ ++it)
+ {
+ if (*it) {
+ delete* it;
+ *it = nullptr;
+ }
+ }
+
+ m_sceneMeshes.clear();
+
+ m_sceneLoaded = false;
+}
+
+const char* SceneManager::getSceneName()
+{
+ return m_sceneName.c_str();
+}
+
+// SceneStaticMesh
+
+SceneStaticMesh::SceneStaticMesh() :
+ m_vb(nullptr),
+ m_ib(nullptr),
+ m_albedoTexture(nullptr),
+ m_vbcount(0),
+ m_ibcount(0)
+{
+}
+
+SceneStaticMesh::~SceneStaticMesh()
+{
+ if (m_ib) {
+ delete m_ib;
+ m_ib = nullptr;
+ }
+
+ if (m_vb) {
+ delete m_vb;
+ m_vb = nullptr;
+ }
+}
+
+void SceneStaticMesh::LoadObj(const char* filename)
+{
+ std::vector vertexIndices, uvIndices, normalIndices;
+ std::vector temp_vertices;
+ std::vector temp_uvs;
+ std::vector temp_normals;
+
+ std::vector out_vertices;
+ std::vector out_uvs;
+ std::vector out_normals;
+
+ FILE* file = fopen(filename, "r");
+ if (file == NULL) {
+ Msg("SceneStaticMesh::LoadObj: Impossible to open the file !");
+ return;
+ }
+
+ while (1) {
+
+ char lineHeader[128];
+ // read the first word of the line
+ int res = fscanf(file, "%s", lineHeader);
+ if (res == EOF)
+ break; // EOF = End Of File. Quit the loop.
+
+ // else : parse lineHeader
+
+ if (strcmp(lineHeader, "v") == 0) {
+ glm::vec3 vertex;
+ fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
+ temp_vertices.push_back(vertex);
+ }
+ else if (strcmp(lineHeader, "vt") == 0) {
+ glm::vec2 uv;
+ fscanf(file, "%f %f\n", &uv.x, &uv.y);
+ uv.y = -uv.y; // Invert V coordinate since we will only use DDS texture, which are inverted. Remove if you want to use TGA or BMP loaders.
+ temp_uvs.push_back(uv);
+ }
+ else if (strcmp(lineHeader, "vn") == 0) {
+ glm::vec3 normal;
+ fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
+ temp_normals.push_back(normal);
+ }
+ else if (strcmp(lineHeader, "f") == 0) {
+ std::string vertex1, vertex2, vertex3;
+ unsigned int vertexIndex[3], uvIndex[3], normalIndex[3];
+ int matches = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexIndex[0], &uvIndex[0], &normalIndex[0], &vertexIndex[1], &uvIndex[1], &normalIndex[1], &vertexIndex[2], &uvIndex[2], &normalIndex[2]);
+ if (matches != 9) {
+ Msg("SceneStaticMesh::LoadObj: File can't be read by our simple parser :-( Try exporting with other options");
+ fclose(file);
+ return;
+ }
+ vertexIndices.push_back(vertexIndex[0]);
+ vertexIndices.push_back(vertexIndex[1]);
+ vertexIndices.push_back(vertexIndex[2]);
+ uvIndices.push_back(uvIndex[0]);
+ uvIndices.push_back(uvIndex[1]);
+ uvIndices.push_back(uvIndex[2]);
+ normalIndices.push_back(normalIndex[0]);
+ normalIndices.push_back(normalIndex[1]);
+ normalIndices.push_back(normalIndex[2]);
+ }
+ else {
+ // Probably a comment, eat up the rest of the line
+ char stupidBuffer[1000];
+ fgets(stupidBuffer, 1000, file);
+ }
+
+ }
+
+ // For each vertex of each triangle
+ for (unsigned int i = 0; i < vertexIndices.size(); i++) {
+
+ // Get the indices of its attributes
+ unsigned int vertexIndex = vertexIndices[i];
+ unsigned int uvIndex = uvIndices[i];
+ unsigned int normalIndex = normalIndices[i];
+
+ // Get the attributes thanks to the index
+ glm::vec3 vertex = temp_vertices[vertexIndex - 1];
+ glm::vec2 uv = temp_uvs[uvIndex - 1];
+ glm::vec3 normal = temp_normals[normalIndex - 1];
+
+ // Put the attributes in buffers
+ out_vertices.push_back(vertex);
+ out_uvs.push_back(uv);
+ out_normals.push_back(normal);
+
+ }
+
+ fclose(file);
+
+ m_boundingBox.m_min = glm::vec3(FLT_MAX);
+ m_boundingBox.m_max = glm::vec3(FLT_MIN);
+
+ // Combine in to the one array
+ std::vector vertices;
+ for (unsigned int i = 0; i < vertexIndices.size(); i++)
+ {
+ // Get the indices of its attributes
+ unsigned int vertexIndex = vertexIndices[i];
+ unsigned int uvIndex = uvIndices[i];
+ unsigned int normalIndex = normalIndices[i];
+
+ // Get the attributes thanks to the index
+ glm::vec3 vertex = temp_vertices[vertexIndex - 1];
+ glm::vec2 uv = temp_uvs[uvIndex - 1];
+ glm::vec3 normal = temp_normals[normalIndex - 1];
+
+ StaticMeshVertex vtx = {};
+ vtx.position = vertex;
+ vtx.normal = normal;
+ vtx.texcoord = uv;
+ vertices.push_back(vtx);
+
+ if (i == 0)
+ {
+ m_boundingBox.m_min = vertex;
+ m_boundingBox.m_max = vertex;
+ }
+ else
+ {
+ m_boundingBox.m_min = glm::min(m_boundingBox.m_min, vertex);
+ m_boundingBox.m_max = glm::max(m_boundingBox.m_max, vertex);
+ }
+ }
+
+// m_Vertices = vertices;
+
+ m_vb = g_renderDevice->CreateVertexBuffer(vertices.data(), (int)sizeof(StaticMeshVertex) * (int)vertices.size());
+ m_vbcount = vertices.size();
+
+ std::string mtlfilename = getFileNameWithoutExtension(filename);
+ mtlfilename += ".mtl";
+ LoadMtl(mtlfilename.c_str());
+}
+
+void SceneStaticMesh::LoadMtl(const char* filename)
+{
+ FILE* file = fopen(filename, "r");
+ if (file == NULL) {
+ Msg("SceneStaticMesh::LoadObj: Impossible to open the file !");
+ return;
+ }
+
+ while (1) {
+
+ char lineHeader[128];
+ // read the first word of the line
+ int res = fscanf(file, "%s", lineHeader);
+ if (res == EOF)
+ break; // EOF = End Of File. Quit the loop.
+
+ if (strcmp(lineHeader, "map_Kd") == 0) {
+ char stupidBuffer[1000];
+ fgets(stupidBuffer, 1000, file);
+
+ const char* textureFilename = stupidBuffer + 1;
+ m_albedoTexture = g_texturesManager->LoadTexture2D(textureFilename, true);
+ }
+
+ //if (strcmp(lineHeader, "v") == 0) {
+ // glm::vec3 vertex;
+ // fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
+ // temp_vertices.push_back(vertex);
+ //}
+ //else {
+ // // Probably a comment, eat up the rest of the line
+ // char stupidBuffer[1000];
+ // fgets(stupidBuffer, 1000, file);
+ //}
+
+ }
+
+ fclose(file);
+}
+
+void SceneStaticMesh::RenderObjects()
+{
+ extern Shader* g_litShader;
+
+ SDL_assert(g_litShader);
+
+ glFrontFace(GL_CCW);
+ glDepthFunc(GL_LESS);
+
+ g_renderDevice->SetCullFace(true);
+ g_renderDevice->SetDepthTest(true);
+ g_renderDevice->SetDepthWrite(true);
+
+ g_renderDevice->SetBlending(false);
+
+ g_renderDevice->SetVerticesBuffer(m_vb);
+
+ g_shaderSystem->SetShader(g_litShader);
+
+ static glm::mat4 s_identity = glm::mat4(1.0f);
+ g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MODEL_MATRIX, &s_identity[0]);
+
+ glm::mat4 mvp = glm::identity();
+ mvp = g_render->GetProjectionMatrix() * g_render->GetViewMatrix();
+ g_shaderSystem->SetUniformMatrix(g_litShader, UNIFORM_MVP_MATRIX, &mvp[0]);
+
+ g_texturesManager->SetTexture(0, m_albedoTexture);
+ g_shaderSystem->SetUniformSampler(g_litShader, SAMPLER_ALBEDO, 0);
+
+ g_renderDevice->DrawArrays(PT_TRIANGLES, 0, m_vbcount);
+}
diff --git a/src/render/scenemanager.h b/src/render/scenemanager.h
new file mode 100644
index 0000000..4b5ee99
--- /dev/null
+++ b/src/render/scenemanager.h
@@ -0,0 +1,73 @@
+#ifndef SCENEMANAGER_H
+#define SCENEMANAGER_H
+
+#include
+#include
+
+class Texture2D;
+class GPUBuffer;
+class Model;
+
+class SceneStaticMesh
+{
+public:
+ SceneStaticMesh();
+ ~SceneStaticMesh();
+
+ void LoadObj(const char* filename);
+ void LoadMtl(const char* filename);
+
+ const BoundingBox& GetBoundingBox() { return m_boundingBox; }
+
+ void RenderObjects();
+
+private:
+ GPUBuffer* m_vb;
+ GPUBuffer* m_ib;
+ uint32_t m_vbcount;
+ uint32_t m_ibcount;
+ BoundingBox m_boundingBox;
+ Texture2D* m_albedoTexture;
+};
+
+class SceneManager
+{
+public:
+ SceneManager();
+ ~SceneManager();
+
+ // \brief Load an static scene.
+ void loadScene(const char*);
+
+ // \brief Get current scene name.
+ const char* getSceneName();
+
+private:
+ void LoadSceneXML(const char* filename);
+ void loadSkybox(const char*);
+ void loadStaticMeshes();
+ void loadStaticMesh(const char* filename);
+public:
+ bool isSceneLoaded();
+
+ void renderScene(const glm::mat4& cameraTranslation);
+
+ void unloadScene();
+ void unloadIfScenePresent();
+
+ void replaceMaterial(const char* oldMaterialname, const char* newMaterialName);
+ void replaceAllMaterialsWithBruteForce(const char* materialname);
+
+
+private:
+ Model* m_pSkybox;
+ std::list m_sceneMeshes;
+ std::string m_sceneFilename;
+ std::string m_sceneName;
+ Texture2D* m_lightmap;
+ bool m_sceneLoaded;
+};
+
+extern SceneManager* g_sceneManager;
+
+#endif // !SCENEMANAGER_H
\ No newline at end of file
diff --git a/src/render/shadersystem.cpp b/src/render/shadersystem.cpp
index 03fa364..e51d18c 100644
--- a/src/render/shadersystem.cpp
+++ b/src/render/shadersystem.cpp
@@ -59,7 +59,7 @@ size_t g_vertexAttribsRealSizeTable[VERTEXATTR_MAX] =
4, // VERTEXATTR_UINT
};
-ShaderSystem* g_pShaderSystem = nullptr;
+ShaderSystem* g_shaderSystem = nullptr;
ShaderSystem::ShaderSystem()
{
diff --git a/src/render/shadersystem.h b/src/render/shadersystem.h
index c962f63..38e6a9f 100644
--- a/src/render/shadersystem.h
+++ b/src/render/shadersystem.h
@@ -27,6 +27,6 @@ private:
std::vector m_shaders;
};
-extern ShaderSystem* g_pShaderSystem;
+extern ShaderSystem* g_shaderSystem;
#endif // !SHADERSYSTEM_H
diff --git a/src/render/texturesmanager.cpp b/src/render/texturesmanager.cpp
index d75a11b..96337ed 100644
--- a/src/render/texturesmanager.cpp
+++ b/src/render/texturesmanager.cpp
@@ -11,7 +11,7 @@
static const char* g_texFileExtensions[] = { ".png", ".jpeg", ".jpg", ".tga", ".bmp" };
const int kTexFileExtensionsSize = sizeof(g_texFileExtensions) / sizeof(g_texFileExtensions[0]);
-TexturesManager* g_pTexturesManager = nullptr;
+TexturesManager* g_texturesManager = nullptr;
static std::string getFileExtension(const std::string& filename)
{
diff --git a/src/render/texturesmanager.h b/src/render/texturesmanager.h
index 5051be0..e46e012 100644
--- a/src/render/texturesmanager.h
+++ b/src/render/texturesmanager.h
@@ -35,6 +35,6 @@ private:
Texture2D* m_notex;
};
-extern TexturesManager* g_pTexturesManager;
+extern TexturesManager* g_texturesManager;
#endif // !TEXTURESMANAGER_H