diff --git a/CMakeLists.txt b/CMakeLists.txt index bbbedff..a788217 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,7 +49,7 @@ CPMAddPackage( CPMAddPackage( NAME JGL - URL https://git.redacted.cc/josh/JGL/archive/Prerelease-16.zip + URL https://git.redacted.cc/josh/JGL/archive/Prerelease-20.zip ) CPMAddPackage( diff --git a/include/Redacted3D/engine/world.h b/include/Redacted3D/engine/world.h index 3592781..b1b1a1c 100644 --- a/include/Redacted3D/engine/world.h +++ b/include/Redacted3D/engine/world.h @@ -49,7 +49,7 @@ private: Vector3 globalLightColor = {0, 0, 0}; Vector4 globalFogColor = {0, 0, 0, 0}; Vector2 globalFogRange = {0, 0}; - GLenum globalFogMode = NULL; ///There's Linear, GL_EXP, GL_EXP2. + GLenum globalFogMode = 0; ///There's Linear, GL_EXP, GL_EXP2. GLfloat globalFogDensity = 0.0f; public: diff --git a/include/Redacted3D/types/entity/entity.h b/include/Redacted3D/types/entity/entity.h index 4f0617e..556eb82 100644 --- a/include/Redacted3D/types/entity/entity.h +++ b/include/Redacted3D/types/entity/entity.h @@ -18,23 +18,25 @@ private: ///Pitch Yaw Roll, The orientation of the entity in the world, Vector3 angle = {0,0,0}; ///Loads the texture for the entity. - virtual void loadTexture(); - ///Loads the geometry for it. - void loadGeometry(); + ///The scale it should be rendered at. - GLfloat scale = 1.0f; + Vector3 scale = {1.0f, 1.0f, 1.0f}; protected: - std::string modelPath; - std::string texturePath; ///If the entity has a parent entity, It's here. Entity* parent; ///Entity list of child entities. std::vector children; + +///Loads the geometry for it. +void loadGeometry(const std::string& file); +void loadTexture(const std::string& file); +void loadMultiTexture(const std::vector& files); +void loadMotionTexture(const std::vector& files, u16 frameDelta, bool doAnim = true); + public: std::string name; //Entity name. TODO remove this. bool alive; - virtual std::vector GetEntityUUIDList() const { return std::vector { "" }; } template @@ -75,7 +77,7 @@ public: [[nodiscard]] Entity* GetFamilyTreeRoot() const; Entity *Add(Entity *newChild); void setScale(const float& multiplier); - [[nodiscard]] GLfloat getScale() const; + [[nodiscard]] Vector3 getScale() const; // TODO: Constrain to DerivedEntityType template diff --git a/include/Redacted3D/types/shader.h b/include/Redacted3D/types/shader.h index 9921172..083f2c6 100644 --- a/include/Redacted3D/types/shader.h +++ b/include/Redacted3D/types/shader.h @@ -8,11 +8,11 @@ public: std::string name; ///The shader program - GLuint id = NULL; + GLuint id = 0; ///The individual shaders - GLuint vertex = NULL; - GLuint fragment = NULL; + GLuint vertex = 0; + GLuint fragment = 0; Shader(const char* name, const std::string& vertexPath, const std::string& fragmentPath); Shader(const char* name, const std::string& filePath, const GLenum& type); diff --git a/include/Redacted3D/types/texture.h b/include/Redacted3D/types/texture.h index b420d1c..572697b 100644 --- a/include/Redacted3D/types/texture.h +++ b/include/Redacted3D/types/texture.h @@ -33,22 +33,24 @@ public: void erase() override; ///Every texture other than the base texture. std::vector multi; - ///Loads a multi-texture from a given directory. One must be called "default.png" - MultiTexture(Entity* entity, const char* pathContainingTextures, bool storeOnTextureList); + ///Loads a list of Textures into a MultiTexture. + MultiTexture(Entity* entity, const std::vector& textures, 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 how much time has elapsed. class MotionTexture : public Texture { private: std::chrono::high_resolution_clock::time_point lastUpdate; - int lastDisplayedIndex; - u16 msDelay; -public: + int lastDisplayedIndex = 0; + u16 msDelay = 0; bool doAnim = true; +public: std::vector motion; Texture* current(); - MotionTexture(Entity* entity, const std::vector& textures,u16 msBetweenFrames, bool storeOnTextureList); + Texture* base(); + void advance(); + void toggleAnim(); + MotionTexture(Entity* entity, const std::vector& textures,u16 msBetweenFrames, bool storeOnTextureList, bool doAnim = true); MotionTexture() = default; }; \ No newline at end of file diff --git a/src/demo/RuntimeTest/include/cube.h b/src/demo/RuntimeTest/include/cube.h index 9f38e34..20bb6c5 100644 --- a/src/demo/RuntimeTest/include/cube.h +++ b/src/demo/RuntimeTest/include/cube.h @@ -17,8 +17,7 @@ public: //The "camera point" is the position the camera will want to be while following the player. //We will probably end up having a different camera point class controlled by the "world". - void update(float elapsed) override; + //void update(float elapsed) override; void pre_render() override; - void loadTexture() override; Cube(); }; \ No newline at end of file diff --git a/src/demo/RuntimeTest/main.cpp b/src/demo/RuntimeTest/main.cpp index 69b1f20..38c24c4 100644 --- a/src/demo/RuntimeTest/main.cpp +++ b/src/demo/RuntimeTest/main.cpp @@ -10,7 +10,7 @@ int main() engine->window = new ReWindow::RWindow("Re3D Test Application", 1152, 864, RenderingAPI::OPENGL); engine->world = new(World); Engine::init(); - JGL::InitTextEngine(); + JGL::Update(engine->window->getSize()); Fonts::initFonts(); engine->window->setVsyncEnabled(false); engine->window->setResizable(false); diff --git a/src/demo/RuntimeTest/src/ball.cpp b/src/demo/RuntimeTest/src/ball.cpp index ada22f0..85ab380 100644 --- a/src/demo/RuntimeTest/src/ball.cpp +++ b/src/demo/RuntimeTest/src/ball.cpp @@ -10,7 +10,7 @@ void Ball::update(float elapsed) { Ball::Ball() { name = "ball"; - modelPath = "assets/models/sphere_lo.obj"; - texturePath = "assets/textures/missing.png"; + loadGeometry("assets/models/sphere_lo.obj"); + loadTexture("assets/textures/missing.png"); setScale(1.0f); -} +} \ No newline at end of file diff --git a/src/demo/RuntimeTest/src/cube.cpp b/src/demo/RuntimeTest/src/cube.cpp index 3e4542f..93a75e7 100644 --- a/src/demo/RuntimeTest/src/cube.cpp +++ b/src/demo/RuntimeTest/src/cube.cpp @@ -1,31 +1,27 @@ #include #include -#include void Cube::pre_render() { getGeometry(); setAngle(getAngle().Add(24 * engine->frameDelta)); } -void Cube::update(float elapsed) { - -} Cube::Cube() { name = "cube"; - modelPath = "assets/models/cube.obj"; - texturePath = "assets/textures/multi/"; setScale(0.5f); -} -void Cube::loadTexture() { - //MultiTexture texture(this, texturePath.c_str(), true); - std::vector textures; - textures.emplace_back("assets/textures/motion/default.png"); - textures.emplace_back("assets/textures/motion/1.png"); - textures.emplace_back("assets/textures/motion/2.png"); - textures.emplace_back("assets/textures/motion/3.png"); - textures.emplace_back("assets/textures/motion/4.png"); - textures.emplace_back("assets/textures/motion/5.png"); - textures.emplace_back("assets/textures/motion/6.png"); - MotionTexture texture(this, textures, 250, true); + loadGeometry("assets/models/cube.obj"); + std::vector motionTextures = { + "assets/textures/motion/default.png", "assets/textures/motion/1.png", "assets/textures/motion/2.png", + "assets/textures/motion/3.png", "assets/textures/motion/4.png", "assets/textures/motion/5.png", + "assets/textures/motion/6.png" + }; + + std::vector multiTextures = { + "assets/textures/multi/default.png", "assets/textures/multi/1.png", "assets/textures/multi/2.png", "assets/textures/multi/3.png", + "assets/textures/multi/4.png", "assets/textures/multi/5.png", "assets/textures/multi/6.png" + }; + + loadMultiTexture(multiTextures); + //loadMotionTexture(motionTextures, 250, true); } diff --git a/src/demo/RuntimeTest/src/demoSky.cpp b/src/demo/RuntimeTest/src/demoSky.cpp index b1c0774..17113a4 100644 --- a/src/demo/RuntimeTest/src/demoSky.cpp +++ b/src/demo/RuntimeTest/src/demoSky.cpp @@ -3,7 +3,7 @@ DemoSkybox::DemoSkybox() { name = "skybox"; - modelPath = engine->workingDir + "/assets/models/sphere_vlo.obj"; - texturePath = engine->workingDir + "/assets/textures/skybox.png"; + loadGeometry("assets/models/sphere_vlo.obj"); + loadTexture("assets/textures/skybox.png"); setScale(engine->farPlane); } \ No newline at end of file diff --git a/src/demo/RuntimeTest/src/freeCam.cpp b/src/demo/RuntimeTest/src/freeCam.cpp index 82cd3da..e307d82 100644 --- a/src/demo/RuntimeTest/src/freeCam.cpp +++ b/src/demo/RuntimeTest/src/freeCam.cpp @@ -37,14 +37,23 @@ void FreeCam::pre_render() { if (engine->window->isKeyDown(Keys::E)) setAngle(getAngle().x, getAngle().y, getAngle().z + 75.0f * engine->frameDelta); - } +Vector3 textAngle = {0,0,0}; void FreeCam::jglRenderPass() { - JGL::J3D::DrawString3D(JGL::Colors::White, "Entity Count: " + std::to_string(engine->world->getEntityCount()), {2.5,0,0}, -0.005125, 48, Fonts::ModeSeven); - JGL::J3D::DrawString3D(JGL::Colors::White, "Cam Pos: X: " + std::to_string(position.x) + " Y: " + std::to_string(position.y) + " Z: " + std::to_string(position.z), {4.75, 0.25,0}, -0.005125, 32, Fonts::ModeSeven); + textAngle.x = textAngle.x - (96.f * engine->frameDelta); + using namespace JGL; + J3D::Begin(); + J3D::DrawString(JGL::Colors::Red, "Text", {0, -2, 0}, textAngle, 4.f, 32, Fonts::Jupiteroid); + J3D::End(); - JGL::J3D::DrawString3D(JGL::Colors::White, "FPS: " + std::to_string(engine->framerate()), {0,0,0}, -0.005125, 48, Fonts::ModeSeven); - JGL::J3D::DrawString3D(JGL::Colors::White, "Framecount: " + std::to_string(engine->frameCount), {0,0.25,0}, -0.005125, 48, Fonts::ModeSeven); - JGL::J3D::DrawString3D(JGL::Colors::White, "Frame dT: " + std::to_string(engine->frameDelta), {0,0.5,0}, -0.005125, 48, Fonts::ModeSeven); + J2D::Begin(); + J2D::FillRect({255,0,0,128}, {0, 72}, {100, 100}); + J2D::FillCircle(JGL::Colors::White, {16, 128}, 12, 16); + + J2D::DrawString(JGL::Colors::White, "Framerate: " + std::to_string((int) engine->framerate()), 0, -16, 1, 16, Fonts::Jupiteroid); + J2D::DrawString(JGL::Colors::White, "Framecount: " + std::to_string(engine->frameCount), 0, -33, 1,16, Fonts::Jupiteroid); + J2D::DrawString(JGL::Colors::White, "Position: " + std::to_string(position.x) + " " + std::to_string(position.y) + " " + std::to_string(position.z), 0, -50, 1,16, Fonts::Jupiteroid); + J2D::DrawString(JGL::Colors::White, "ViewAngle: " + std::to_string(getAngle().x) + " " + std::to_string(getAngle().y) + " " + std::to_string(getAngle().z), 0, -67, 1,16, Fonts::Jupiteroid); + J2D::End(); } diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 624d076..d8b084f 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1,7 +1,9 @@ #include #include +#include #include #include +#include using namespace J3ML; @@ -80,6 +82,7 @@ void Engine::initGL() const { glDepthMask(GL_TRUE); glEnable(GL_CULL_FACE); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glEnable(GL_LIGHT0); } void Engine::init() { @@ -109,11 +112,15 @@ void Engine::render() { if (auto* c = dynamic_cast(e); c == nullptr) //If it's not a camera. e->render(); - if (glGetError() != GL_NO_ERROR) + int glError = glGetError(); + if (glError != GL_NO_ERROR) { + FATAL("GL Error: " + std::to_string(glError)) exit(0); + } } void Engine::jglRenderPass() { + JGL::Update(engine->window->getSize()); glDisable(GL_LIGHTING); ///If elements are attached to a camera that's not the active one then they shouldn't be drawn. if(world->getActiveCamera() != nullptr) diff --git a/src/types/entity/entity.cpp b/src/types/entity/entity.cpp index ce7724b..30e2c9b 100644 --- a/src/types/entity/entity.cpp +++ b/src/types/entity/entity.cpp @@ -42,7 +42,7 @@ Entity::Entity() { ticksAlive = 0; children = std::vector (); parent = nullptr; - scale = 1.0f; + scale = {1.0f, 1.0f, 1.0f}; //UUIDv4::UUIDGenerator uuidGenerator; //UUIDv4::UUID id = uuidGenerator.getUUID(); @@ -50,24 +50,43 @@ Entity::Entity() { } void Entity::setScale(const float &multiplier) { - scale = multiplier; + scale.Set(multiplier, multiplier, multiplier); } -GLfloat Entity::getScale() const { +Vector3 Entity::getScale() const { return scale; } -void Entity::loadTexture() { - Texture texture(this, texturePath.c_str(), true); +void Entity::loadTexture(const std::string& file) { + for (const auto* e : engine->world->GetChildren()) + if (instanceOf(this, e)) + return; + Texture texture(this, file.c_str(), true); } -void Entity::loadGeometry() { - VertexArray vArray(this, modelPath, true); +void Entity::loadMultiTexture(const std::vector& files) { + for (const auto* e : engine->world->GetChildren()) + if (instanceOf(this, e)) + return; + MultiTexture texture(this, files, true); +} + +void Entity::loadMotionTexture(const std::vector& files, u16 frameDelta, bool doAnim) { + for (const auto* e : engine->world->GetChildren()) + if (instanceOf(this, e)) + return; + MotionTexture(this, files, frameDelta, true, doAnim); +} + +void Entity::loadGeometry(const std::string& file) { + for (const auto& vA : engine->world->geometryList) + for (const auto& reference : vA->usedBy) + if (instanceOf(this, reference)) + return; + VertexArray vArray(this, file, true); } VertexArray* Entity::getGeometry() { - if (engine->world->geometryList.empty()) - loadGeometry(); for (auto& vArray : engine->world->geometryList) for (auto& entity : vArray->usedBy) if (instanceOf(this, entity)) { @@ -75,28 +94,60 @@ VertexArray* Entity::getGeometry() { vArray->usedBy.push_back(this); return vArray; } - loadGeometry(); - return getGeometry(); + return nullptr; } +Texture* Entity::getTexture() { + for (auto& texture : engine->world->textureList) + for (auto& entity : texture->usedBy) + if (instanceOf(this, entity)) { + if (std::find(texture->usedBy.begin(), texture->usedBy.end(), this) == texture->usedBy.end()) //If this is the first time the entity is using it. + texture->usedBy.push_back(this); + return texture; + } + return nullptr; +} + +inline Texture* baseTexture = new Texture; void Entity::render() { - bool multiTexture = false; - bool motionTexture = false; + if (!baseTexture) { + Texture t; + glGenTextures(1, &t.id); + glBindTexture(GL_TEXTURE_2D, t.id); - if (auto* t = dynamic_cast(getTexture())) - multiTexture = true; + unsigned char whitePixel[4] = { 255, 255, 255, 255}; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, whitePixel); - if (!multiTexture) - if (auto* t = dynamic_cast(getTexture())) - motionTexture = true; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glActiveTexture(0); + baseTexture = new Texture(t); + } + + MultiTexture texture; + texture.id = baseTexture->id; + + if (auto* t = dynamic_cast(getTexture())) { + texture.multi.emplace_back(*t); + for (const auto &item: t->multi) + texture.multi.push_back(item); + } + + else if (auto* j = dynamic_cast(getTexture())) + texture.multi.push_back(*j->current()); + + else if (auto* k = dynamic_cast(getTexture())) + texture.multi.push_back(*k); glPushMatrix(); glTranslatef(position.x, position.y, position.z); glRotatef(angle.x, 1.0f, 0.0f, 0.0f); glRotatef(angle.y, 0.0f, 1.0f, 0.0f); glRotatef(angle.z, 0.0f, 0.0f, 1.0f); - if (getScale() != 1.0f) - glScalef(getScale(), getScale(), getScale()); + if (getScale().x != 1.0f || getScale().y != 1.0f || getScale().z != 1.0f) + glScalef(getScale().x, getScale().y, getScale().z); //Set up texture. glActiveTexture(GL_TEXTURE0); @@ -104,7 +155,9 @@ void Entity::render() { glEnable(GL_TEXTURE_2D); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glBindTexture(GL_TEXTURE_2D, motionTexture ? ((MotionTexture*)getTexture())->current()->id : getTexture()->id); + glBindTexture(GL_TEXTURE_2D, texture.id); + //Texture unit mode. + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (!engine->useVBO) glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &getGeometry()->vertices[0].x), @@ -114,41 +167,32 @@ void Entity::render() { glBindBuffer(GL_ARRAY_BUFFER, getGeometry()->tbo), glTexCoordPointer(2, GL_FLOAT, 0, nullptr); - if (!multiTexture) - getGeometry()->draw(); - if (multiTexture) { - auto* multi = (MultiTexture*) getTexture(); + int i = 0; + for(auto& t : texture.multi) { + glActiveTexture(GL_TEXTURE1 + i); + glClientActiveTexture(GL_TEXTURE1 + i); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); - int i = 0; - GLfloat blendingFactor[3] = {engine->world->getAmbientLightColor().x * 0.2f, engine->world->getAmbientLightColor().y * 0.2f, engine->world->getAmbientLightColor().z * 0.2f}; - for(auto& texture : multi->multi) { - glActiveTexture(GL_TEXTURE1 + i); - glClientActiveTexture(GL_TEXTURE1 + i); - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (!engine->useVBO) + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &getGeometry()->vertices[0].x), + glTexCoordPointer(2, GL_FLOAT, sizeof(TextureCoordinate), &getGeometry()->texCoords[0].x); - if (!engine->useVBO) - glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &getGeometry()->vertices[0].x), - glTexCoordPointer(2, GL_FLOAT, sizeof(TextureCoordinate), &getGeometry()->texCoords[0].x); - - if (engine->useVBO) - glBindBuffer(GL_ARRAY_BUFFER, getGeometry()->tbo), - glTexCoordPointer(2, GL_FLOAT, 0, nullptr); + if (engine->useVBO) + glBindBuffer(GL_ARRAY_BUFFER, getGeometry()->tbo), + glTexCoordPointer(2, GL_FLOAT, 0, nullptr); //Texture unit mode. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); - - //Makes the lighting work the way you'd think it would. - glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, blendingFactor); - glBindTexture(GL_TEXTURE_2D, texture.id); + glBindTexture(GL_TEXTURE_2D, t.id); i++; } getGeometry()->draw(); //Reset the multi-texture units. - for (int j = 0; j <= i; j++) { + for (int j = 0; j < i; j++) { glActiveTexture(GL_TEXTURE1 + j); glClientActiveTexture(GL_TEXTURE1 + j); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -156,7 +200,6 @@ void Entity::render() { glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } - } //Reset texture unit 0. glActiveTexture(GL_TEXTURE0); @@ -180,20 +223,6 @@ void Entity::render() { //bool Entity::isCollidingWith(Entity *entity) {} -Texture* Entity::getTexture() { - if (engine->world->textureList.empty()) - loadTexture(); - for (auto& texture : engine->world->textureList) - for (auto& entity : texture->usedBy) - if (instanceOf(this, entity)) { - if (std::find(texture->usedBy.begin(), texture->usedBy.end(), this) == texture->usedBy.end()) //If this is the first time the entity is using it. - texture->usedBy.push_back(this); - return texture; - } - loadTexture(); - return getTexture(); -} - void Entity::erase() { Texture* t = getTexture(); VertexArray* vA = getGeometry(); @@ -220,9 +249,10 @@ void Entity::erase() { AABB Entity::getAABB() { AABB aabb = Collision::genMinimallyEnclosingAABB(getGeometry()); - if (getScale() != 1) - aabb.minPoint *= scale, - aabb.maxPoint *= scale; + //TODO this won't look right. + if (getScale().x != 1) + aabb.minPoint *= scale.x, + aabb.maxPoint *= scale.x; aabb.minPoint += position; aabb.maxPoint += position; @@ -231,7 +261,8 @@ AABB Entity::getAABB() { Sphere Entity::getSphere() { Sphere sphere = Collision::genMinimallyEnclosingSphere(getGeometry()); - sphere.Radius *= scale; + //TODO this won't look right. + sphere.Radius *= scale.x; sphere.Position = position; return sphere; } diff --git a/src/types/entity/skybox.cpp b/src/types/entity/skybox.cpp index 1f7d7da..941b45c 100644 --- a/src/types/entity/skybox.cpp +++ b/src/types/entity/skybox.cpp @@ -12,7 +12,7 @@ void Skybox::render() { glTranslatef(position.x ,position.y, position.z); glBindTexture(GL_TEXTURE_2D, getTexture()->id); glCullFace(GL_FRONT); - glScalef(getScale(), getScale(), getScale()); + glScalef(getScale().x, getScale().y, getScale().z); getGeometry()->draw(); glCullFace(GL_BACK); glBindTexture(GL_TEXTURE_2D,0); @@ -21,7 +21,5 @@ void Skybox::render() { Skybox::Skybox() { name = "skybox"; - modelPath = engine->workingDir + "/assets/models/sphere_vlo.obj"; - texturePath = engine->workingDir + "/assets/textures/missing.png"; setScale(engine->farPlane); } \ No newline at end of file diff --git a/src/types/texture.cpp b/src/types/texture.cpp index 5123fc0..d30afb4 100644 --- a/src/types/texture.cpp +++ b/src/types/texture.cpp @@ -1,9 +1,10 @@ -#include #include +#include #include void Texture::load(Entity* entity, const std::string& file, bool storeOnTextureList) { auto* texture = new RTexture(file, {RTextureFlag::INVERT_Y}); + glGenTextures(1, &id); glBindTexture(GL_TEXTURE_2D, id); if (texture->format == RTextureFormat::RGBA) @@ -11,6 +12,7 @@ void Texture::load(Entity* entity, const std::string& file, bool storeOnTextureL if (texture->format == RTextureFormat::RGB) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texture->width, texture->height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture->pixelData.data()); delete texture; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -55,35 +57,31 @@ void Texture::erase(Texture* texture) const { engine->world->textureList.erase(engine->world->textureList.begin() + i); } - -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(entity, (const char*) entry.path().c_str(), false); - - //The base texture *must* go in the first slot. - if (entry.path().filename() == "default.png") - this->id = texture.id, - this->usedBy = texture.usedBy; - else multi.push_back(texture); - } +MultiTexture::MultiTexture(Entity* entity, const std::vector& textures, bool storeOnTextureList) { + Texture base; + for (const auto& t : textures) { + if (id != 0) + multi.emplace_back(entity, t.c_str(), false); + else + base = Texture(entity, t.c_str(), false), + id = base.id, + usedBy = base.usedBy; + } if (storeOnTextureList) engine->world->textureList.push_back(new MultiTexture(*this)); - //You cannot have more than 8 total textures rendered in one pass. - //In Fixed-Function OpenGL you only have 8 TMUs available. - //TODO: multi-pass multi-texturing (will be slower). - if (multi.size() > 7) - engine->setError(ENGINE_ERROR_CODE::MULTI_TEXTURE_SIZE_EXCEEDS, true); + if (multi.size() > 6) + engine->setError(ENGINE_ERROR_CODE::MULTI_TEXTURE_SIZE_EXCEEDS, false); } void MultiTexture::erase() { Texture::erase(this); } -MotionTexture::MotionTexture(Entity* entity, const std::vector& textures, u16 msBetweenFrames, bool storeOnTextureList) { +MotionTexture::MotionTexture(Entity* entity, const std::vector& textures, u16 msBetweenFrames, bool storeOnTextureList, bool doAnim) { msDelay = msBetweenFrames; + this->doAnim = doAnim; Texture base(entity, textures[0].c_str(), false); std::vector extra(textures.begin()+1, textures.end()); @@ -124,4 +122,18 @@ Texture* MotionTexture::current() { return this; return &motion[lastDisplayedIndex - 1]; -} \ No newline at end of file +} + +void MotionTexture::advance() { + lastDisplayedIndex++; + if (lastDisplayedIndex > motion.size()) + lastDisplayedIndex = 0; +} + +void MotionTexture::toggleAnim() { + doAnim = !doAnim; +} + +Texture* MotionTexture::base() { + return this; +}