better model and texture cleanup
This commit is contained in:
parent
b269e8059a
commit
9d0262e8a2
7 changed files with 120 additions and 30 deletions
|
@ -20,7 +20,8 @@ Engine::Engine(int width, int height, std::string name, const char *icon) : xeWi
|
|||
};
|
||||
|
||||
Engine::~Engine() {
|
||||
xe::Model::submitDeleteQueue();
|
||||
Model::submitDeleteQueue(true);
|
||||
Image::submitDeleteQueue(true);
|
||||
alutExit();
|
||||
};
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
namespace xe {
|
||||
|
||||
//
|
||||
// CONSTRUCTORS AND DECONSTUCTORS
|
||||
//
|
||||
|
||||
Image::Image(const std::string &filename, bool anisotropic) : xeDevice{Engine::getInstance()->xeDevice} {
|
||||
createTextureImage(filename);
|
||||
createTextureImageView();
|
||||
|
@ -24,6 +28,43 @@ Image::~Image() {
|
|||
vkDestroyImageView(xeDevice.device(), textureImageView, nullptr);
|
||||
}
|
||||
|
||||
//
|
||||
// LOADERS AND DELETORS
|
||||
//
|
||||
|
||||
static std::set<Image*> CREATED_IMAGES{};
|
||||
static std::set<Image*> DELETION_QUEUE{};
|
||||
|
||||
Image* Image::createImage(const std::string &filename, bool anisotropic) {
|
||||
Image* image = new Image(filename, anisotropic);
|
||||
CREATED_IMAGES.insert(image);
|
||||
return image;
|
||||
}
|
||||
|
||||
void Image::deleteImage(Image* image) {
|
||||
if(CREATED_IMAGES.count(image)) {
|
||||
CREATED_IMAGES.erase(image);
|
||||
DELETION_QUEUE.insert(image);
|
||||
}
|
||||
}
|
||||
|
||||
void Image::submitDeleteQueue(bool purge) {
|
||||
for(Image* image: DELETION_QUEUE) {
|
||||
try { delete image; } catch(int err) {};
|
||||
}
|
||||
DELETION_QUEUE.clear();
|
||||
if (purge) {
|
||||
for(Image* image: CREATED_IMAGES) {
|
||||
try { delete image; } catch(int err) {};
|
||||
}
|
||||
CREATED_IMAGES.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// IMAGE CREATION FUNCTIONS
|
||||
//
|
||||
|
||||
void Image::createTextureImage(const std::string &filename) {
|
||||
int texWidth, texHeight, texChannels;
|
||||
stbi_uc* pixels = stbi_load(filename.c_str(), &texWidth, &texHeight, &texChannels, STBI_rgb_alpha);
|
||||
|
@ -243,6 +284,10 @@ void Image::createTextureSampler(bool anisotropic) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// STATIC CREATE IMAGE
|
||||
//
|
||||
|
||||
void Image::createImage(Device& device, uint32_t width, uint32_t height, uint32_t mipLevels, VkSampleCountFlagBits numSamples, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage& image, VkDeviceMemory& imageMemory) {
|
||||
|
||||
VkImageCreateInfo imageInfo{};
|
||||
|
@ -279,6 +324,10 @@ void Image::createImage(Device& device, uint32_t width, uint32_t height, uint32_
|
|||
vkBindImageMemory(device.device(), image, imageMemory, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// STATIC CREATE IMAGE VIEW
|
||||
//
|
||||
|
||||
VkImageView Image::createImageView(Device& device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels) {
|
||||
VkImageViewCreateInfo viewInfo{};
|
||||
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "xe_device.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace xe {
|
||||
|
||||
|
@ -10,7 +11,9 @@ class Image {
|
|||
|
||||
public:
|
||||
|
||||
Image(const std::string &filename, bool anisotropic);
|
||||
static Image* createImage(const std::string &filename, bool anisotropic);
|
||||
static void deleteImage(Image* image);
|
||||
|
||||
~Image();
|
||||
|
||||
Image(const Image&) = delete;
|
||||
|
@ -18,6 +21,10 @@ class Image {
|
|||
|
||||
private:
|
||||
|
||||
static void submitDeleteQueue(bool purge);
|
||||
|
||||
Image(const std::string &filename, bool anisotropic);
|
||||
|
||||
void createTextureImage(const std::string &filename);
|
||||
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||
void generateMipmaps(VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels);
|
||||
|
@ -38,6 +45,7 @@ class Image {
|
|||
|
||||
friend class RenderSystem;
|
||||
friend class SwapChain;
|
||||
friend class Engine;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
namespace xe {
|
||||
|
||||
//
|
||||
// CONSTRUCTORS AND DECONSTUCTORS
|
||||
//
|
||||
|
||||
Model::Model(const Model::Builder &builder) : xeDevice{Engine::getInstance()->xeDevice} {
|
||||
createVertexBuffers(builder.vertexData.data, builder.vertexSize);
|
||||
createIndexBuffers(builder.indices);
|
||||
|
@ -21,12 +25,49 @@ Model::Model(const Model::Builder &builder) : xeDevice{Engine::getInstance()->xe
|
|||
|
||||
Model::~Model() {}
|
||||
|
||||
Model* Model::createModelFromFile(const std::string &filepath) {
|
||||
//
|
||||
// LOADERS AND DELETORS
|
||||
//
|
||||
|
||||
static std::set<Model*> CREATED_MODELS{};
|
||||
static std::set<Model*> DELETION_QUEUE{};
|
||||
|
||||
Model* Model::createModel(const std::string &filepath) {
|
||||
Builder builder{};
|
||||
builder.loadModel(filepath);
|
||||
return new Model(builder);
|
||||
return createModel(builder);
|
||||
}
|
||||
|
||||
Model* Model::createModel(Builder& builder) {
|
||||
Model* model = new Model(builder);
|
||||
CREATED_MODELS.insert(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
void Model::deleteModel(Model* model) {
|
||||
if(CREATED_MODELS.count(model)) {
|
||||
CREATED_MODELS.erase(model);
|
||||
DELETION_QUEUE.insert(model);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::submitDeleteQueue(bool purge) {
|
||||
for(Model* model: DELETION_QUEUE) {
|
||||
try { delete model; } catch(int err) {};
|
||||
}
|
||||
DELETION_QUEUE.clear();
|
||||
if (purge) {
|
||||
for(Model* model: CREATED_MODELS) {
|
||||
try { delete model; } catch(int err) {};
|
||||
}
|
||||
CREATED_MODELS.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MODEL CREATION FUNCTIONS
|
||||
//
|
||||
|
||||
void Model::createVertexBuffers(const std::vector<unsigned char> &vertexData, uint32_t vertexSize) {
|
||||
vertexCount = static_cast<uint32_t>(vertexData.size()) / vertexSize;
|
||||
assert(vertexCount >= 3 && "Vertex count must be atleast 3");
|
||||
|
@ -155,21 +196,4 @@ void Model::Builder::loadModel(const std::string &filepath) {
|
|||
|
||||
}
|
||||
|
||||
static std::vector<Model*> deleteQueue{};
|
||||
|
||||
void Model::deleteModel(Model* model) {
|
||||
deleteQueue.push_back(model);
|
||||
}
|
||||
|
||||
void Model::submitDeleteQueue() {
|
||||
for(Model* model : deleteQueue) {
|
||||
if(model == nullptr) return;
|
||||
try {
|
||||
delete model;
|
||||
} catch (int err) {}
|
||||
}
|
||||
deleteQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -34,20 +34,24 @@ class Model {
|
|||
void loadModel(const std::string &filepath);
|
||||
};
|
||||
|
||||
Model(const Model::Builder &builder);
|
||||
static Model* createModel(const std::string &filepath);
|
||||
static Model* createModel(Builder& builder);
|
||||
static void deleteModel(Model* model);
|
||||
|
||||
~Model();
|
||||
|
||||
Model(const Model &) = delete;
|
||||
Model operator=(const Model &) = delete;
|
||||
|
||||
static Model* createModelFromFile(const std::string &filepath);
|
||||
static void deleteModel(Model* model);
|
||||
static void submitDeleteQueue();
|
||||
|
||||
void bind(VkCommandBuffer commandBuffer);
|
||||
void draw(VkCommandBuffer commandBuffer);
|
||||
|
||||
private:
|
||||
|
||||
static void submitDeleteQueue(bool purge);
|
||||
|
||||
Model(const Model::Builder &builder);
|
||||
|
||||
void createVertexBuffers(const std::vector<unsigned char> &vertexData, uint32_t vertexSize);
|
||||
void createIndexBuffers(const std::vector<uint32_t> &indexData);
|
||||
|
||||
|
@ -59,6 +63,9 @@ class Model {
|
|||
bool hasIndexBuffer = false;
|
||||
std::unique_ptr<Buffer> indexBuffer;
|
||||
uint32_t indexCount;
|
||||
|
||||
friend class SwapChain;
|
||||
friend class Engine;
|
||||
};
|
||||
|
||||
}
|
|
@ -88,7 +88,8 @@ VkResult SwapChain::submitCommandBuffers(
|
|||
vkWaitForFences(device.device(), 1, &imagesInFlight[*imageIndex], VK_TRUE, UINT64_MAX);
|
||||
}
|
||||
|
||||
Model::submitDeleteQueue();
|
||||
Model::submitDeleteQueue(false);
|
||||
Image::submitDeleteQueue(false);
|
||||
|
||||
imagesInFlight[*imageIndex] = inFlightFences[currentFrame];
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ static std::map<std::string, uint32_t> texturesIds{};
|
|||
static std::vector<xe::Image*> textures{};
|
||||
|
||||
void loadTexture(const std::string& filePath) {
|
||||
xe::Image* image = new xe::Image(filePath, false);
|
||||
xe::Image* image = xe::Image::createImage(filePath, false);
|
||||
texturesIds[filePath] = static_cast<uint32_t>(textures.size());
|
||||
textures.push_back(image);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ void Chunk::load() {
|
|||
|
||||
void Chunk::unload() {
|
||||
for(const auto &image: textures) {
|
||||
delete image;
|
||||
xe::Image::deleteImage(image);
|
||||
}
|
||||
for(const auto &[key, chunk]: chunks) {
|
||||
delete chunk;
|
||||
|
@ -163,7 +163,7 @@ xe::Model* Chunk::getMesh() {
|
|||
xe::Model::Builder builder{};
|
||||
builder.vertexData = vertexData;
|
||||
builder.vertexSize = 36;
|
||||
chunkMesh = new xe::Model(builder);
|
||||
chunkMesh = xe::Model::createModel(builder);
|
||||
reloadRequired = false;
|
||||
}
|
||||
return chunkMesh;
|
||||
|
|
Loading…
Reference in a new issue