spriteAPI.h 4.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #ifndef DFPSR_SPRITE_ENGINE
  2. #define DFPSR_SPRITE_ENGINE
  3. #include "../../../DFPSR/includeFramework.h"
  4. #include "orthoAPI.h"
  5. #include "lightAPI.h"
  6. #include <assert.h>
  7. #include <limits>
  8. namespace dsr {
  9. // TODO: Make into a constructor for each vector type
  10. inline FVector3D parseFVector3D(const ReadableString& content) {
  11. List<ReadableString> args = string_split(content, U',');
  12. if (args.length() != 3) {
  13. printText("Expected a vector of three decimal values.\n");
  14. return FVector3D();
  15. } else {
  16. return FVector3D(string_parseDouble(args[0]), string_parseDouble(args[1]), string_parseDouble(args[2]));
  17. }
  18. }
  19. // The sprite instance itself has a game-specific index to the sprite type
  20. // The caller should also have some kind of control over containing and rendering the items
  21. struct Sprite {
  22. public:
  23. int typeIndex;
  24. Direction direction;
  25. IVector3D location; // Displayed at X, Y-Z in world pixel coordinates
  26. bool shadowCasting;
  27. public:
  28. Sprite(int typeIndex, Direction direction, const IVector3D& location, bool shadowCasting)
  29. : typeIndex(typeIndex), direction(direction), location(location), shadowCasting(shadowCasting) {}
  30. };
  31. class SpriteWorldImpl;
  32. using SpriteWorld = std::shared_ptr<SpriteWorldImpl>;
  33. int sprite_loadTypeFromFile(const String& folderPath, const String& spriteName);
  34. int sprite_getTypeCount();
  35. // TODO: Create the ortho system using the content of its configuration file to hide the type itself.
  36. SpriteWorld spriteWorld_create(OrthoSystem ortho, int shadowResolution);
  37. void spriteWorld_addBackgroundSprite(SpriteWorld& world, const Sprite& sprite);
  38. void spriteWorld_addTemporarySprite(SpriteWorld& world, const Sprite& sprite);
  39. // Create a point light that only exists until the next call to spriteWorld_clearTemporary.
  40. // position is in tile unit world-space.
  41. void spriteWorld_createTemporary_pointLight(SpriteWorld& world, const FVector3D position, float radius, float intensity, ColorRgbI32 color, bool shadowCasting);
  42. void spriteWorld_createTemporary_directedLight(SpriteWorld& world, const FVector3D direction, float intensity, ColorRgbI32 color);
  43. void spriteWorld_clearTemporary(SpriteWorld& world);
  44. void spriteWorld_draw(SpriteWorld& world, AlignedImageRgbaU8& colorTarget);
  45. // The result is an approximation in mini-tile units.
  46. // The 3D system does not align with screen pixels for less than whole tile units.
  47. // TODO: See if an exact float position can be returned from pixelToMiniOffset instead of using integers that are less precise.
  48. IVector3D spriteWorld_findGroundAtPixel(SpriteWorld& world, const AlignedImageRgbaU8& colorBuffer, const IVector2D& pixelLocation);
  49. // Approximates a mini-tile offset along the ground from the given pixel offset and moves the camera accordingly
  50. // If the offset is too small, the camera might not move at all
  51. void spriteWorld_moveCameraInPixels(SpriteWorld& world, const IVector2D& pixelOffset);
  52. // Get internal buffers after rendering.
  53. // Reading before having drawn the world for the first time will return null because the world does not yet know the target resolution.
  54. // By not being a part of rendering itself, it cannot go back in time and speed up rendering, so only use for debugging.
  55. // TODO: Make another feature for actually disabling dynamic light on low-end machines.
  56. AlignedImageRgbaU8 spriteWorld_getDiffuseBuffer(SpriteWorld& world);
  57. OrderedImageRgbaU8 spriteWorld_getNormalBuffer(SpriteWorld& world);
  58. OrderedImageRgbaU8 spriteWorld_getLightBuffer(SpriteWorld& world);
  59. AlignedImageF32 spriteWorld_getHeightBuffer(SpriteWorld& world);
  60. // Access the index of the camera's fixed direction
  61. // This is not an index selecting the camera itself, only selecting the viewing angle
  62. // TODO: Implement bound checks or a system that's easier to understand.
  63. int spriteWorld_getCameraDirectionIndex(SpriteWorld& world);
  64. void spriteWorld_setCameraDirectionIndex(SpriteWorld& world, int index);
  65. // Pre-conditions:
  66. // The model should be pre-transformed so that it can be rendered at the world origin
  67. // Textures must be converted into vertex colors or else they will simply be ignored
  68. // Enabling debug will save another file using a *Debug.png prefix with additional information
  69. // Use it to find flaws in generated shadow shapes that are hard to see in raw data
  70. // TODO: Hide OrthoSystem or expose it safely
  71. void sprite_generateFromModel(const Model& visibleModel, const Model& shadowModel, const OrthoSystem& ortho, const String& targetPath, int cameraAngles, bool debug = false);
  72. // A simpler version writing the result to an image and a string instead of saving to files.
  73. void sprite_generateFromModel(ImageRgbaU8& targetAtlas, String& targetConfigText, const Model& visibleModel, const Model& shadowModel, const OrthoSystem& ortho, const String& targetPath, int cameraAngles);
  74. }
  75. #endif