Guest User

Untitled

a guest
Oct 17th, 2021
8
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Corrade/Containers/GrowableArray.h>
  2. #include <Corrade/Utility/Arguments.h>
  3. #include <Magnum/GL/Context.h>
  4. #include <Magnum/GL/DefaultFramebuffer.h>
  5. #include <Magnum/GL/Buffer.h>
  6. #include <Magnum/GL/Mesh.h>
  7. #include <Magnum/Math/ConfigurationValue.h>
  8. #include <Magnum/Math/DualComplex.h>
  9. #include <Magnum/MeshTools/Compile.h>
  10. #include <Magnum/Platform/Sdl2Application.h>
  11. #include <Magnum/Primitives/Square.h>
  12. #include <Magnum/Primitives/Plane.h>
  13. #include <Magnum/Primitives/Cube.h>
  14. #include <Magnum/SceneGraph/Camera.h>
  15. #include <Magnum/SceneGraph/Drawable.h>
  16. #include <Magnum/SceneGraph/TranslationRotationScalingTransformation2D.h>
  17. #include <Magnum/SceneGraph/TranslationRotationScalingTransformation3D.h>
  18. #include <Magnum/SceneGraph/Scene.h>
  19. #include <Magnum/Shaders/FlatGL.h>
  20. #include <Magnum/Trade/MeshData.h>
  21. #include <Magnum/GL/Texture.h>
  22. #include <Magnum/GL/TextureFormat.h>
  23. #include <Magnum/ResourceManager.h>
  24. #include <Magnum/Trade/AbstractImporter.h>
  25. #include <Magnum/Trade/ImageData.h>
  26. #include <Magnum/ImageView.h>
  27. #include <Magnum/GL/Buffer.h>
  28. #include <Magnum/GL/DefaultFramebuffer.h>
  29. #include <Magnum/GL/BufferImage.h>
  30. #include <Magnum/DebugTools/ResourceManager.h>
  31. #include <Magnum/DebugTools/ObjectRenderer.h>
  32. #include <Magnum/GL/Renderer.h>
  33. #include <Magnum/Shaders/PhongGL.h>
  34.  
  35. #include <utility>
  36. #include <iostream>
  37. #include <map>
  38.  
  39. std::string imagepath = R"(C:\IMAGEPATHHERE\)";
  40.  
  41.  
  42. using namespace Magnum;
  43.  
  44. DebugTools::ResourceManager manager;
  45. SceneGraph::DrawableGroup3D debugDrawables;
  46.  
  47. using Scene3D = SceneGraph::Scene<SceneGraph::TranslationRotationScalingTransformation3D>;
  48. using Object3D = SceneGraph::Object<SceneGraph::TranslationRotationScalingTransformation3D>;
  49.  
  50. using namespace Math::Literals;
  51.  
  52. std::map<std::string, Vector3i> pngpos = {{"001.png", {376, 218, 0}},{"002.png", {385, 418, 0}},{"003.png", {332, 375, 0}},{"004.png", {430, 383, 0}},{"005.png", {341, 566, 0}},{"006.png", {438, 563, 0}},};
  53. static constexpr unsigned int DimensionsCount = 3;
  54. using TileCoord = int;
  55. using TilePosition = Vector3i;
  56. static constexpr TilePosition RegionDimensions = {10, 10, 5};
  57.  
  58. class Sprite;
  59. class SpriteGroup;
  60. class Rock;
  61.  
  62. struct TestGameObject
  63. {
  64. std::string png;
  65. Vector3i pos;
  66.  
  67. Sprite* sprite = nullptr; //two way
  68.  
  69. explicit TestGameObject(const std::string& png) : png(png), pos(pngpos[png]) {}
  70. };
  71.  
  72. struct TestRootObject
  73. {
  74. TilePosition pos;
  75.  
  76. std::vector<TestGameObject*> objects;
  77.  
  78. SpriteGroup* spritegroup = nullptr; //two way
  79.  
  80. explicit TestRootObject(TilePosition pos) : pos(pos) {}
  81. };
  82.  
  83. struct TestTile
  84. {
  85. std::vector<TestRootObject*> roots;
  86. bool hasrock = false;
  87.  
  88. TilePosition pos;
  89.  
  90. Rock* rock = nullptr; //two way
  91. };
  92.  
  93. class TestRegion
  94. {
  95. std::array<TestTile, RegionDimensions[0] * RegionDimensions[1] * RegionDimensions[2]> tiles;
  96.  
  97. inline bool InBounds(TilePosition position)
  98. {
  99. return !(position[0] > RegionDimensions[0] || position[1] > RegionDimensions[1] || position[2] > RegionDimensions[2]);
  100. }
  101.  
  102. void Populate()
  103. {
  104. static constexpr TileCoord FloorHeight = 1;
  105.  
  106. for (TileCoord z = FloorHeight; z < RegionDimensions[2]; ++z)
  107. {
  108. for (TileCoord x = 0; x < RegionDimensions[0]; ++x)
  109. {
  110. (*this)[{x, 0, z}].hasrock = true;
  111. (*this)[{x, RegionDimensions[1] - 1, z}].hasrock = true;
  112. }
  113.  
  114. for (TileCoord y = 0; y < RegionDimensions[1]; ++y)
  115. {
  116. (*this)[{0, y, z}].hasrock = true;
  117. (*this)[{RegionDimensions[0] - 1, y, z}].hasrock = true;
  118. }
  119. }
  120.  
  121. for (TileCoord z = 0; z < FloorHeight; ++z)
  122. {
  123. for (TileCoord x = 0; x < RegionDimensions[0]; ++x)
  124. {
  125. for (TileCoord y = 0; y < RegionDimensions[1]; ++y)
  126. {
  127. (*this)[{x, y, z}].hasrock = true;
  128. }
  129. }
  130. }
  131.  
  132. for (TileCoord z = 0; z < RegionDimensions[2]; ++z)
  133. {
  134. for (TileCoord x = 0; x < RegionDimensions[0]; ++x)
  135. {
  136. for (TileCoord y = 0; y < RegionDimensions[1]; ++y)
  137. {
  138. (*this)[{x, y, z}].pos = {x, y, z};
  139. }
  140. }
  141. }
  142.  
  143. Vector3i minpos{9999999, 9999999, 0};
  144. Vector3i maxpos{-9999999, -9999999, 0};
  145. for (auto& pair : pngpos)
  146. {
  147. pair.second *= Vector3i{1, -1, 1};
  148.  
  149. if (pair.second[0] < minpos[0]) minpos[0] = pair.second[0];
  150. if (pair.second[1] < minpos[1]) minpos[1] = pair.second[1];
  151.  
  152. if (pair.second[0] > maxpos[0]) maxpos[0] = pair.second[0];
  153. if (pair.second[1] > maxpos[1]) maxpos[1] = pair.second[1];
  154. }
  155.  
  156. Vector3i midpoint = (maxpos + minpos) / 2;
  157.  
  158. for (auto& pair : pngpos) pair.second -= midpoint;
  159.  
  160. // for (auto& pair : pngpos)
  161. // {
  162. // Debug() << pair.first << ": " << pair.second << '\n';
  163. // }
  164.  
  165. TilePosition start = {RegionDimensions[0] / 2, RegionDimensions[1] / 2, FloorHeight};
  166. auto& tile = (*this)[start];
  167.  
  168. player = new TestRootObject(start);
  169.  
  170. for (auto& pair : pngpos)
  171. {
  172. player->objects.push_back(new TestGameObject(pair.first));
  173. }
  174.  
  175. tile.roots.push_back(player);
  176. }
  177.  
  178. public:
  179. TestRegion()
  180. {
  181. Populate();
  182. }
  183.  
  184. TestRootObject* player = nullptr;
  185.  
  186. TestTile& operator[](TilePosition position)
  187. {
  188. if (!InBounds(position))
  189. {
  190. //overflow
  191.  
  192. std::cout << "overflow" << std::endl;
  193. throw;
  194. }
  195.  
  196. return tiles[position[0] + (position[1] * RegionDimensions[0]) + (position[2] * RegionDimensions[0] * RegionDimensions[1])];
  197. }
  198. };
  199.  
  200.  
  201.  
  202. /*
  203. * https://doc.magnum.graphics/magnum/classMagnum_1_1Trade_1_1AbstractImporter.html
  204. * https://doc.magnum.graphics/magnum/file-formats.html
  205. *
  206. * https://doc.magnum.graphics/magnum/classMagnum_1_1Trade_1_1AbstractImporter.html#a88703d241d03b605112b2163778529b2
  207. * https://doc.magnum.graphics/corrade/classCorrade_1_1Containers_1_1ArrayView.html
  208. */
  209.  
  210. static constexpr int TilePixelScale = 800; //400 pixels cube for now?
  211. static constexpr Vector3i TilePixelDimensions = {TilePixelScale, TilePixelScale, TilePixelScale};
  212. static constexpr Vector3i TilePixelCenter = {TilePixelDimensions[0] / 2, TilePixelDimensions[1] / 2, TilePixelDimensions[2] / 2};
  213. static constexpr float PixelScale = 1.0f / 1000.0f; //1 might be the entire screen width, so I have to scale down considerably
  214.  
  215. ResourceManager<GL::Texture2D> texturemanager;
  216. PluginManager::Manager<Trade::AbstractImporter> importermanager;
  217.  
  218. void LoadImage(std::string imagename)
  219. {
  220. Containers::Pointer<Trade::AbstractImporter> importer =
  221. importermanager.loadAndInstantiate("AnyImageImporter");
  222. if(!importer || !importer->openFile(imagepath + imagename))
  223. Fatal{} << "Can't open image.png with AnyImageImporter";
  224.  
  225. Containers::Optional<Trade::ImageData2D> image = importer->image2D(0);
  226. if(!image) Fatal{} << "Importing the image failed";
  227.  
  228. GL::Texture2D _texture;
  229. _texture.setWrapping(GL::SamplerWrapping::ClampToEdge)
  230. .setMagnificationFilter(GL::SamplerFilter::Linear)
  231. .setMinificationFilter(GL::SamplerFilter::Linear)
  232. .setStorage(1, GL::textureFormat(image->format()), image->size())
  233. .setSubImage(0, {}, *image);
  234.  
  235. texturemanager.set(imagename, std::move(_texture), ResourceDataState::Final, ResourcePolicy::Resident);
  236. }
  237.  
  238. auto GetImage(std::string imagename)
  239. {
  240. auto texture = Resource<GL::Texture2D>{texturemanager.get<GL::Texture2D>(imagename)};
  241.  
  242. if (!texture) LoadImage(imagename);
  243.  
  244. return texture;
  245. }
  246.  
  247. /*
  248. * https://doc.magnum.graphics/magnum/classMagnum_1_1GL_1_1CubeMapTexture.html
  249. */
  250.  
  251. class Rock;
  252.  
  253. struct TileBlockVertex {
  254. Vector3 position;
  255. Vector2 textureCoordinates;
  256. } TileBlockVertices[]{
  257. {{-1.0f, -1.0f, 1.0f}, { 0.0f, 0.0f}},
  258. {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f}},
  259. {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f}}, /* +Z */
  260. {{-1.0f, 1.0f, 1.0f}, { 0.0f, 1.0f}},
  261.  
  262. {{ 1.0f, -1.0f, 1.0f}, { 0.0f, 1.0f}},
  263. {{ 1.0f, -1.0f, -1.0f}, { 0.0f, 0.0f}},
  264. {{ 1.0f, 1.0f, -1.0f}, { 1.0f, 0.0f}}, /* +X */
  265. {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f}},
  266.  
  267. {{-1.0f, 1.0f, 1.0f}, { 0.0f, 1.0f}},
  268. {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f}},
  269. {{ 1.0f, 1.0f, -1.0f}, { 1.0f, 0.0f}}, /* +Y */
  270. {{-1.0f, 1.0f, -1.0f}, { 0.0f, 0.0f}},
  271.  
  272. {{ 1.0f, -1.0f, -1.0f}, { 1.0f, 0.0f}},
  273. {{-1.0f, -1.0f, -1.0f}, { 0.0f, 0.0f}},
  274. {{-1.0f, 1.0f, -1.0f}, { 0.0f, 1.0f}}, /* -Z */
  275. {{ 1.0f, 1.0f, -1.0f}, { 1.0f, 1.0f}},
  276.  
  277. {{-1.0f, -1.0f, -1.0f}, { 0.0f, 0.0f}},
  278. {{ 1.0f, -1.0f, -1.0f}, { 1.0f, 0.0f}},
  279. {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f}}, /* -Y */
  280. {{-1.0f, -1.0f, 1.0f}, { 0.0f, 1.0f}},
  281.  
  282. {{-1.0f, -1.0f, -1.0f}, {0.0f, 0.0f}},
  283. {{-1.0f, -1.0f, 1.0f}, {0.0f, 1.0f}},
  284. {{-1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}}, /* -X */
  285. {{-1.0f, 1.0f, -1.0f}, {1.0f, 0.0f}}
  286. };
  287.  
  288. constexpr struct TileBlockVertex2 {
  289. Vector3 position;
  290. Vector3 normal;
  291. Vector2 textureCoordinates;
  292. } TileBlockVertices2[]{
  293. {{-1.0f, -1.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f}},
  294. {{ 1.0f, -1.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f}},
  295. {{ 1.0f, 1.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 1.0f}}, /* +Z */
  296. {{-1.0f, 1.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 1.0f}},
  297.  
  298. {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 1.0f}},
  299. {{ 1.0f, -1.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f}},
  300. {{ 1.0f, 1.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f}}, /* +X */
  301. {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}, { 1.0f, 1.0f}},
  302.  
  303. {{-1.0f, 1.0f, 1.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f}},
  304. {{ 1.0f, 1.0f, 1.0f}, { 0.0f, 1.0f, 0.0f}, { 1.0f, 1.0f}},
  305. {{ 1.0f, 1.0f, -1.0f}, { 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}}, /* +Y */
  306. {{-1.0f, 1.0f, -1.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
  307.  
  308. {{ 1.0f, -1.0f, -1.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f}},
  309. {{-1.0f, -1.0f, -1.0f}, { 0.0f, 0.0f, -1.0f}, { 0.0f, 0.0f}},
  310. {{-1.0f, 1.0f, -1.0f}, { 0.0f, 0.0f, -1.0f}, { 0.0f, 1.0f}}, /* -Z */
  311. {{ 1.0f, 1.0f, -1.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 1.0f}},
  312.  
  313. {{-1.0f, -1.0f, -1.0f}, { 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f}},
  314. {{ 1.0f, -1.0f, -1.0f}, { 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f}},
  315. {{ 1.0f, -1.0f, 1.0f}, { 0.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}}, /* -Y */
  316. {{-1.0f, -1.0f, 1.0f}, { 0.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
  317.  
  318. {{-1.0f, -1.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
  319. {{-1.0f, -1.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
  320. {{-1.0f, 1.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}, {1.0f, 1.0f}}, /* -X */
  321. {{-1.0f, 1.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}, {1.0f, 0.0f}}
  322. };
  323.  
  324.  
  325. constexpr UnsignedShort TileBlockIndices[]{
  326. 0, 1, 2, 0, 2, 3, /* +Z */
  327. 4, 5, 6, 4, 6, 7, /* +X */
  328. 8, 9, 10, 8, 10, 11, /* +Y */
  329. 12, 13, 14, 12, 14, 15, /* -Z */
  330. 16, 17, 18, 16, 18, 19, /* -Y */
  331. 20, 21, 22, 20, 22, 23 /* -X */
  332. };
  333.  
  334. Trade::MeshAttributeData AttributesSolid[]{
  335. Trade::MeshAttributeData{Trade::MeshAttribute::Position,
  336. Containers::stridedArrayView(TileBlockVertices, &TileBlockVertices[0].position,
  337. Containers::arraySize(TileBlockVertices), sizeof(TileBlockVertex))},
  338. Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates,
  339. Containers::stridedArrayView(TileBlockVertices, &TileBlockVertices[0].textureCoordinates,
  340. Containers::arraySize(TileBlockVertices), sizeof(TileBlockVertex))}
  341. };
  342.  
  343. Trade::MeshAttributeData AttributesSolid2[]{
  344. Trade::MeshAttributeData{Trade::MeshAttribute::Position,
  345. Containers::stridedArrayView(TileBlockVertices2, &TileBlockVertices2[0].position,
  346. Containers::arraySize(TileBlockVertices2), sizeof(TileBlockVertex2))},
  347. Trade::MeshAttributeData{Trade::MeshAttribute::Normal,
  348. Containers::stridedArrayView(TileBlockVertices2, &TileBlockVertices2[0].normal,
  349. Containers::arraySize(TileBlockVertices2), sizeof(TileBlockVertex2))},
  350. Trade::MeshAttributeData{Trade::MeshAttribute::TextureCoordinates,
  351. Containers::stridedArrayView(TileBlockVertices2, &TileBlockVertices2[0].textureCoordinates,
  352. Containers::arraySize(TileBlockVertices2), sizeof(TileBlockVertex2))}
  353. };
  354.  
  355. Trade::MeshData cubeSolid() {
  356. return Trade::MeshData{MeshPrimitive::Triangles,
  357. {}, TileBlockIndices, Trade::MeshIndexData{TileBlockIndices},
  358. {}, TileBlockVertices, Trade::meshAttributeDataNonOwningArray(AttributesSolid)};
  359. }
  360.  
  361.  
  362.  
  363.  
  364. class TerrainCategory : public Object3D
  365. {
  366.  
  367. SceneGraph::DrawableGroup3D drawables;
  368.  
  369. Shaders::FlatGL3D shader{
  370. Shaders::FlatGL3D::Flag::Textured|
  371. Shaders::FlatGL3D::Flag::TextureTransformation};
  372. // Shaders::PhongGL shader{Shaders::PhongGL::Flag::DiffuseTexture};
  373.  
  374. GL::Mesh mesh = MeshTools::compile(cubeSolid());
  375.  
  376. public:
  377. explicit TerrainCategory(Scene3D& parent) : Object3D(&parent)
  378. {
  379. // mesh.addVertexBuffer(vertices, 0,
  380. // Shaders::PhongGL::Position{},
  381. // Shaders::PhongGL::Normal{},
  382. // Shaders::PhongGL::TextureCoordinates{})
  383. // .setCount(24)
  384. // .setIndexBuffer(indices, 0, GL::MeshIndexType::UnsignedShort, 0, 24);
  385.  
  386.  
  387. // mesh.addVertexBuffer(vertices, 0,
  388. // Shaders::FlatGL3D::Position{},
  389. // Shaders::FlatGL3D::TextureCoordinates{})
  390. // .setCount(24)
  391. // .setIndexBuffer(indices, 0, GL::MeshIndexType::UnsignedShort, 0, 24);
  392. }
  393.  
  394. void draw(SceneGraph::Camera3D& camera)
  395. {
  396. camera.draw(drawables);
  397. }
  398.  
  399. Rock& MakeRock(TestTile& tile);
  400.  
  401. friend Rock;
  402. };
  403.  
  404. inline Vector3i GetTileOffset(TestTile& tile)
  405. {
  406. auto tilecoordpixels = tile.pos * TilePixelScale;
  407. return tilecoordpixels * Vector3i{1, -1, 1}; //need to invert y axis
  408. }
  409.  
  410. /* https://doc.magnum.graphics/magnum/classMagnum_1_1Shaders_1_1FlatGL.html#Shaders-FlatGL-textured
  411. * This is how I'll make this work, I need to change the cube mesh I use to having a 3d position and 2d texture position on each vertex
  412. * So I'll probably make my own custom mesh
  413. *
  414. * I'll copy and paste the array from the cube thing, I'll do texture coordinates by basically looking at the 2 dimensions in play
  415. * -1 turns to 0, and 1 turns to 1 for texture coordinates
  416. * I'll see how I want orientation stuff later
  417. */
  418.  
  419. class Rock : public Object3D, public SceneGraph::Drawable3D
  420. {
  421. Resource<GL::Texture2D> texture;
  422. TerrainCategory& category;
  423.  
  424. TestTile* tile = nullptr; //two way
  425.  
  426. void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) override
  427. {
  428. auto size = Vector3(TilePixelDimensions) / 4.0f;
  429.  
  430. // category.shader
  431. // .setTransformationMatrix(transformation*Matrix4::scaling(size))
  432. // .setProjectionMatrix(camera.projectionMatrix())
  433. // .bindDiffuseTexture(*texture)
  434. // .draw(category.mesh);
  435.  
  436. category.shader
  437. .setTransformationProjectionMatrix(camera.projectionMatrix()*transformation*Matrix4::scaling(size))
  438. .bindTexture(*texture)
  439. .draw(category.mesh);
  440. }
  441.  
  442. public:
  443. Rock(TestTile& tile, TerrainCategory& category) :
  444. Object3D(&category), Drawable(*this, &category.drawables), texture(GetImage("dirt.png")), category(category), tile(&tile)
  445. {
  446. this->setTranslation(Vector3(GetTileOffset(tile)));
  447.  
  448. new DebugTools::ObjectRenderer3D{manager, *this, "my", &debugDrawables};
  449. }
  450.  
  451. friend TerrainCategory;
  452. };
  453.  
  454. Rock& TerrainCategory::MakeRock(TestTile& tile)
  455. {
  456. return *(new Rock(tile, *this));
  457. }
  458.  
  459. class SpriteCategory : public Object3D //this will be owned by a scene, but not a real object
  460. {
  461. SceneGraph::DrawableGroup3D drawables;
  462. Shaders::FlatGL3D shader{
  463. Shaders::FlatGL3D::Flag::Textured|
  464. Shaders::FlatGL3D::Flag::TextureTransformation};
  465. GL::Mesh mesh = MeshTools::compile(Primitives::planeSolid(Primitives::PlaneFlag::TextureCoordinates));
  466.  
  467.  
  468. public:
  469. explicit SpriteCategory(Scene3D& parent) : Object3D(&parent)
  470. {
  471.  
  472. }
  473.  
  474. void draw(SceneGraph::Camera3D& camera)
  475. {
  476. // GL::Renderer::enable(GL::Renderer::Feature::Blending);
  477.  
  478. camera.draw(drawables);
  479.  
  480. // GL::Renderer::disable(GL::Renderer::Feature::Blending);
  481. }
  482.  
  483. SpriteGroup& MakeGroup(TestRootObject& root);
  484.  
  485. friend Sprite;
  486. friend SpriteGroup;
  487. };
  488.  
  489. inline Vector3i GetOffset(TestRootObject& root)
  490. {
  491. auto tilecoordpixels = root.pos * TilePixelScale;
  492. return tilecoordpixels * Vector3i{1, -1, 1}; //need to invert y axis
  493. }
  494.  
  495. class SpriteGroup : public Object3D
  496. {
  497. SpriteCategory& category;
  498.  
  499. TestRootObject* root; //two way
  500.  
  501. SpriteGroup(TestRootObject& root, SpriteCategory& category) : Object3D(&category), category(category), root(&root)
  502. {
  503. this->setTranslation(Vector3(GetOffset()));
  504. }
  505. public:
  506. inline Vector3i GetOffset()
  507. {
  508. return ::GetOffset(*root);
  509. }
  510.  
  511. Sprite& MakeSprite(TestGameObject& object);
  512.  
  513. friend Sprite;
  514. friend SpriteCategory;
  515. };
  516.  
  517. SpriteGroup& SpriteCategory::MakeGroup(TestRootObject& root)
  518. {
  519. return *(new SpriteGroup(root, *this));
  520. }
  521.  
  522. class Sprite : public Object3D, public SceneGraph::Drawable3D
  523. {
  524. Resource<GL::Texture2D> texture;
  525. SpriteGroup& group;
  526.  
  527. TestGameObject* object; //two way
  528.  
  529. void draw(const Matrix4& transformation, SceneGraph::Camera3D& camera) override
  530. {
  531. auto size = Vector3(Vector2(texture->imageSize(0)), 0.0f) / 2.0f;
  532.  
  533. group.category.shader
  534. .setTransformationProjectionMatrix(camera.projectionMatrix()*transformation*Matrix4::scaling(size))
  535. .bindTexture(*texture)
  536. .draw(group.category.mesh);
  537. }
  538.  
  539. Sprite(TestGameObject& object, SpriteGroup& group) :
  540. Object3D(&group), Drawable(*this, &group.category.drawables), texture(GetImage(object.png)), group(group), object(&object)
  541. {
  542. this->setTranslation(Vector3(pngpos[object.png]));
  543.  
  544. // Debug() << object.png << " size: " << texture->imageSize(0);
  545.  
  546. new DebugTools::ObjectRenderer3D{manager, *this, "my", &debugDrawables};
  547. }
  548. public:
  549.  
  550. friend SpriteGroup;
  551. };
  552.  
  553. Sprite& SpriteGroup::MakeSprite(TestGameObject& object)
  554. {
  555. return *(new Sprite(object, *this));
  556. }
  557.  
  558. class MyApplication: public Platform::Application {
  559. public:
  560. explicit MyApplication(const Arguments& arguments);
  561.  
  562. private:
  563. void drawEvent() override;
  564. void mousePressEvent(MouseEvent& event) override;
  565. void mouseMoveEvent(MouseMoveEvent& event) override;
  566.  
  567. Scene3D _scene;
  568. Object3D* _cameraObject;
  569. SceneGraph::Camera3D* _camera;
  570.  
  571. SpriteCategory sprites{_scene};
  572. TerrainCategory terrain{_scene};
  573.  
  574. TestRegion gameregion;
  575.  
  576. Vector2i _previousMousePosition;
  577.  
  578. void ViewRegion()
  579. {
  580. auto IncrementPos = [](TilePosition& pos)
  581. {
  582. ++pos[0];
  583.  
  584. for (unsigned int i = 0; i < DimensionsCount - 1; ++i)
  585. {
  586. if (pos[i] >= RegionDimensions[i])
  587. {
  588. pos[i] = 0;
  589. ++pos[i + 1];
  590. }
  591. }
  592. };
  593.  
  594. auto GetSpriteGroup = [this](TestRootObject& root) -> SpriteGroup&
  595. {
  596. if (!root.spritegroup)
  597. {
  598. root.spritegroup = &sprites.MakeGroup(root);
  599. }
  600.  
  601. return *root.spritegroup;
  602. };
  603.  
  604. auto GetSprite = [](TestGameObject& object, SpriteGroup& group) -> Sprite&
  605. {
  606. if (!object.sprite)
  607. {
  608. object.sprite = &group.MakeSprite(object);
  609. }
  610.  
  611. return *object.sprite;
  612. };
  613.  
  614. auto GetRock = [this](TestTile& tile) -> Rock&
  615. {
  616. if (!tile.rock)
  617. {
  618. tile.rock = &terrain.MakeRock(tile);
  619. }
  620.  
  621. return *tile.rock;
  622. };
  623.  
  624. for (TilePosition pos = {0, 0, 0}; pos[DimensionsCount - 1] < RegionDimensions[DimensionsCount - 1]; IncrementPos(pos))
  625. {
  626. auto& tile = gameregion[pos];
  627.  
  628. if (tile.hasrock)
  629. {
  630. GetRock(tile);
  631. }
  632.  
  633. for (auto* root : tile.roots)
  634. {
  635. if (!root->objects.empty())
  636. {
  637. auto& group = GetSpriteGroup(*root);
  638.  
  639. for (auto* object : root->objects)
  640. {
  641. // if (object->png != "001.png" && object->png != "002.png" && object->png != "003.png") continue;
  642. GetSprite(*object, group);
  643. }
  644. }
  645. }
  646.  
  647. /* Need to set camera position based on player position, player is stored in the region
  648. * I'll eventually need a 3d camera I think, maybe even sprites will have to be 3d objects, I'll have to see
  649. *
  650. * Maybe I should attach the camera object to the player?? Like make the player object its parent, so it inherits the player's translation?
  651. */
  652.  
  653. Vector3i playerpos = GetOffset(*gameregion.player);
  654.  
  655. _cameraObject->setTranslation(Vector3(playerpos) + Vector3{0, 0, 4000});
  656. }
  657. }
  658. };
  659.  
  660. MyApplication::MyApplication(const Arguments& arguments): Platform::Application{arguments} {
  661. /* Try 8x MSAA, fall back to zero samples if not possible. Enable only 2x
  662. MSAA if we have enough DPI. */
  663. // {
  664. // const Vector2 dpiScaling = this->dpiScaling({});
  665. // Configuration conf;
  666. // conf.setTitle("Magnum Box2D Example")
  667. // .setSize(conf.size(), dpiScaling);
  668. // GLConfiguration glConf;
  669. // glConf.setSampleCount(dpiScaling.max() < 2.0f ? 8 : 2);
  670. // if(!tryCreate(conf, glConf))
  671. // create(conf, glConf.setSampleCount(0));
  672. // }
  673.  
  674. GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
  675.  
  676.  
  677. manager.set("my", DebugTools::ObjectRendererOptions{}.setSize(100.0f));
  678.  
  679. /* Configure camera */
  680. _cameraObject = new Object3D{&_scene};
  681. _camera = new SceneGraph::Camera3D{*_cameraObject};
  682. _camera->setAspectRatioPolicy(SceneGraph::AspectRatioPolicy::Extend)
  683. .setProjectionMatrix(Matrix4::perspectiveProjection(35.0_degf, 4.0f/3.0f, 0.001f, 1000000.0f))
  684. .setViewport(GL::defaultFramebuffer.viewport().size());
  685.  
  686. setSwapInterval(1);
  687. #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_ANDROID)
  688. setMinimalLoopPeriod(16);
  689. #endif
  690. }
  691.  
  692. /*
  693. * https://doc.magnum.graphics/magnum/classMagnum_1_1GL_1_1TextureArray.html
  694. * https://doc.magnum.graphics/magnum/classMagnum_1_1Shaders_1_1FlatGL.html#a0137f4b617fef20381737e6201745969afab48552de43c3349089eef161154d07
  695. * https://doc.magnum.graphics/magnum/classMagnum_1_1Shaders_1_1FlatGL.html#ae0819ba94b8b4867fa887cacad2fe134
  696. *
  697. * So I think what I'll do is have a texture array of some kind, and I still have the shader.bindTexture like in the textured triangle example?
  698. * I'll just have an offset/position thing that's also in my instance data, that determines what part of the passed in texture is used for each instance
  699. * I can test this without changing the cubes much (only their class and maybe passing in offsets), if I have some kind of texture array to work with loaded in
  700. */
  701.  
  702. /*
  703. * https://doc.magnum.graphics/magnum/classMagnum_1_1SceneGraph_1_1Drawable.html
  704. * https://doc.magnum.graphics/magnum/scenegraph.html
  705. * https://doc.magnum.graphics/magnum/features.html
  706. * https://doc.magnum.graphics/magnum/classMagnum_1_1ResourceManager.html
  707. */
  708.  
  709. /*
  710. * How to figure out alpha stuff:
  711. * https://doc.magnum.graphics/magnum/classMagnum_1_1Shaders_1_1FlatGL.html#Shaders-FlatGL-alpha
  712. *
  713. * Maybe just subtract the tile center off the camera's position, rather than adding it to everything else's position?
  714. */
  715.  
  716. void MyApplication::drawEvent() {
  717. GL::defaultFramebuffer.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth);
  718.  
  719. ViewRegion();
  720.  
  721. GL::Renderer::enable(GL::Renderer::Feature::DepthTest);
  722.  
  723. sprites.draw(*_camera);
  724. terrain.draw(*_camera);
  725.  
  726. GL::Renderer::disable(GL::Renderer::Feature::DepthTest);
  727.  
  728. _camera->draw(debugDrawables);
  729.  
  730. swapBuffers();
  731. redraw(); //have some way to call when this is necessary?
  732. }
  733.  
  734. void MyApplication::mousePressEvent(MouseEvent& event) {
  735. if(event.button() != MouseEvent::Button::Left) return;
  736.  
  737. _previousMousePosition = event.position();
  738. event.setAccepted();
  739. }
  740.  
  741. void MyApplication::mouseMoveEvent(MouseMoveEvent& event) {
  742. if(!(event.buttons() & MouseMoveEvent::Button::Left)) return;
  743.  
  744. /* We have to take window size, not framebuffer size, since the position is
  745. in window coordinates and the two can be different on HiDPI systems */
  746. const Vector2 delta = 3.0f*
  747. Vector2{event.position() - _previousMousePosition}/
  748. Vector2{windowSize()};
  749.  
  750. (*_cameraObject)
  751. .rotate(Rad{-delta.y()}, _cameraObject->transformation().right().normalized())
  752. .rotateY(Rad{-delta.x()});
  753.  
  754. _previousMousePosition = event.position();
  755. event.setAccepted();
  756. redraw();
  757. }
  758.  
  759. MAGNUM_APPLICATION_MAIN(MyApplication)
  760.  
RAW Paste Data