Motion Textures.
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#include <glad/glad.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <J3ML/LinearAlgebra.h>
|
||||
#include <chrono>
|
||||
|
||||
//Forward declaration of entity.
|
||||
class Entity;
|
||||
@@ -22,6 +24,7 @@ public:
|
||||
///Constructor. Calls load.
|
||||
Texture(Entity* entity, const char *filePath, bool storeOnTextureList);
|
||||
Texture() = default;
|
||||
//virtual ~Texture() = default;
|
||||
};
|
||||
|
||||
///Multi-Texture. One texture in the base slot, 7 in the following slots.
|
||||
@@ -32,10 +35,20 @@ public:
|
||||
std::vector<Texture> multi;
|
||||
///Loads a multi-texture from a given directory. One must be called "default.png"
|
||||
MultiTexture(Entity* entity, const char* pathContainingTextures, bool storeOnTextureList);
|
||||
MultiTexture() = default;
|
||||
//TODO load multi-texture from array of std::string of file names.
|
||||
};
|
||||
|
||||
///A list of textures where the one actually displayed depends on the frame delta.
|
||||
class MotionTexture : public MultiTexture {
|
||||
|
||||
///A list of textures where the one actually displayed depends on how much time has elapsed.
|
||||
class MotionTexture : public Texture {
|
||||
private:
|
||||
std::chrono::high_resolution_clock::time_point lastUpdate;
|
||||
int lastDisplayedIndex;
|
||||
u16 msDelay;
|
||||
public:
|
||||
bool doAnim = true;
|
||||
std::vector<Texture> motion;
|
||||
Texture* current();
|
||||
MotionTexture(Entity* entity, const std::vector<std::string>& textures,u16 msBetweenFrames, bool storeOnTextureList);
|
||||
MotionTexture() = default;
|
||||
};
|
@@ -82,6 +82,7 @@ void Engine::initGL() const {
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
}
|
||||
|
||||
|
@@ -47,8 +47,7 @@ void Texture::erase(Texture* texture) const {
|
||||
MultiTexture::MultiTexture(Entity* entity, const char* pathContainingTextures, bool storeOnTextureList) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(pathContainingTextures))
|
||||
if (entry.is_regular_file() && entry.path().extension() == ".png") {
|
||||
Texture texture;
|
||||
texture.load(entity, entry.path().c_str(), false);
|
||||
Texture texture(entity, entry.path().c_str(), false);
|
||||
|
||||
//The base texture *must* go in the first slot.
|
||||
if (entry.path().filename() == "default.png")
|
||||
@@ -69,4 +68,44 @@ MultiTexture::MultiTexture(Entity* entity, const char* pathContainingTextures, b
|
||||
|
||||
void MultiTexture::erase() {
|
||||
Texture::erase(this);
|
||||
}
|
||||
}
|
||||
|
||||
MotionTexture::MotionTexture(Entity* entity, const std::vector<std::string>& textures, u16 msBetweenFrames, bool storeOnTextureList) {
|
||||
msDelay = msBetweenFrames;
|
||||
Texture base(entity, textures[0].c_str(), false);
|
||||
std::vector<std::string> extra(textures.begin()+1, textures.end());
|
||||
|
||||
if(!extra.empty())
|
||||
for (auto& t : extra)
|
||||
motion.emplace_back(entity, t.c_str(), false);
|
||||
|
||||
id = base.id;
|
||||
usedBy = base.usedBy;
|
||||
if (storeOnTextureList)
|
||||
engine->world->textureList.push_back(new MotionTexture(*this));
|
||||
}
|
||||
|
||||
Texture* MotionTexture::current() {
|
||||
//TODO this will look stupid if their frameDelta is greater than the animation speed. In that event, skip to the frame we should be on.
|
||||
if (!doAnim)
|
||||
return this;
|
||||
|
||||
///If it's our first time getting what the current texture should be.
|
||||
if (lastUpdate == std::chrono::high_resolution_clock::time_point()) {
|
||||
lastUpdate = std::chrono::high_resolution_clock::now();
|
||||
lastDisplayedIndex = -1;
|
||||
return this;
|
||||
}
|
||||
///If the time between now and the last time the texture was drawn is greater than lastUpdate+msDelay.
|
||||
if ((std::chrono::high_resolution_clock::now().time_since_epoch()) - lastUpdate.time_since_epoch() > (lastUpdate.time_since_epoch() + std::chrono::milliseconds(msDelay))) {
|
||||
lastDisplayedIndex++;
|
||||
///If we'd be getting an object outside the bounds of the vector then we'd reset the loop to the base.
|
||||
if (lastDisplayedIndex >= motion.size()) {
|
||||
lastUpdate = std::chrono::high_resolution_clock::now();
|
||||
lastDisplayedIndex = -1;
|
||||
return this;
|
||||
}
|
||||
lastUpdate = std::chrono::high_resolution_clock::now();
|
||||
return &motion[lastDisplayedIndex];
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user