summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-10-02 19:51:10 -0400
committerJonathan Bradley <jcb@pikum.xyz>2023-10-02 19:51:10 -0400
commit4899815c69894bba3eb1a6faa8ccbbc676751728 (patch)
treee3d5895b35d060d193ec59ccdeaf65dfbad6e145 /src
parent2bdee2ce549b1306cafb1d657624eeed4cf7225a (diff)
instancing now works as intended
Diffstat (limited to 'src')
-rw-r--r--src/components.hpp21
-rw-r--r--src/ecs.cpp215
-rw-r--r--src/ecs.hpp3
-rw-r--r--src/entities.cpp42
-rw-r--r--src/game.cpp24
-rw-r--r--src/window.cpp2
6 files changed, 185 insertions, 122 deletions
diff --git a/src/components.hpp b/src/components.hpp
index 06477da..490e798 100644
--- a/src/components.hpp
+++ b/src/components.hpp
@@ -4,8 +4,7 @@
#include "macros.hpp"
#include "dynamic-array.hpp"
-#include <glm/vec2.hpp>
-#include <glm/vec3.hpp>
+#include <glm/gtc/quaternion.hpp>
#include <vulkan/vulkan_core.h>
const uint64_t ECS_UNSET_VAL = 0xFFFFFFFFFFFFFFFF;
@@ -22,12 +21,6 @@ struct Entity {
bool isMarkedForRemoval = false;
};
-struct InstPos {
- glm::vec3 pos;
- glm::vec3 rot;
- glm::vec3 scale;
-};
-
struct CompGrBinds {
EntityHandle entHandle = EntityHandle_MAX;
GrBindsHandle grBindsHandle = GrBindsHandle_MAX;
@@ -53,9 +46,14 @@ struct CompGrBinds {
VkBuffer instanceBuffer = VK_NULL_HANDLE;
uint32_t instanceFirstBinding = 0;
uint32_t instanceBindingCount = 0;
+ uint32_t instanceCounter = 0;
VkDeviceSize instanceOffsets = 0;
- DynArray<InstPos> instances{0};
- bool isInstanceBufferNeedingUpdated = false;
+};
+
+struct InstPos {
+ glm::vec3 pos;
+ glm::quat rot;
+ glm::vec3 scale;
};
struct CompInstance {
@@ -63,7 +61,8 @@ struct CompInstance {
GrBindsHandle grBindsHandle = GrBindsHandle_MAX;
InstanceHandle instanceHandle = InstanceHandle_MAX;
uint64_t index = ECS_UNSET_VAL;
- InstPos *ptr = nullptr;
+ InstPos instPos;
+ bool isNeedingUpdated = false;
};
#endif /* PKE_COMPONENTS_HPP */
diff --git a/src/ecs.cpp b/src/ecs.cpp
index b0f9250..9458506 100644
--- a/src/ecs.cpp
+++ b/src/ecs.cpp
@@ -1,7 +1,8 @@
#include "ecs.hpp"
-#include <new>
+#include "vendor/glm_include.hpp"
+#include "window.hpp"
TypeSafeInt_B(EntityHandle);
const uint64_t maxBucketItemCount = 256;
@@ -115,7 +116,6 @@ void ECS_Tick_Early(double delta) {
instBucketIndex = b;
}
if (inst != nullptr) {
- grBinds->instances.Remove(inst->index);
for (long bi = instBucketIndex; bi <= Comp_Instance_BucketContainer.bucketCounter; ++bi) {
uint64_t instCounter = 0;
if (bi == Comp_Instance_BucketContainer.bucketCounter) {
@@ -132,74 +132,139 @@ void ECS_Tick_Early(double delta) {
continue;
}
bucket.instances[ii].index -= 1;
+ bucket.instances[ii].isNeedingUpdated = true;
}
}
+ grBinds->instanceCounter -=1;
inst->entHandle = EntityHandle_MAX;
inst->grBindsHandle = GrBindsHandle_MAX;
inst->index = ECS_UNSET_VAL;
inst->instanceHandle = InstanceHandle_MAX;
- inst->ptr = CAFE_BABE(InstPos);
+ inst->isNeedingUpdated = false;
} else if (grBinds != nullptr) {
/*
* 2023-09-05 JB note - the Vulkan assets (device memory, buffers,
* pipeline layout, and descriptor set) are unloaded elsewhere, just,
* as they were created elsewhere.
*/
- DynArrayDestroy(&grBinds->instances);
}
}
entitiesMarkedForRemoval.Resize(0);
}
+struct InstanceBufferCopyChunk {
+ uint64_t startingIndex;
+ uint64_t endingIndex;
+ DynArray<glm::mat4> mats{0};
+ VkBufferCopy dstBufferCopy;
+};
+struct InstanceBufferCopy {
+ CompGrBinds *grBinds = nullptr;
+ VkDeviceSize runningSize = 0;
+ DynArray<InstanceBufferCopyChunk> chunks{4};
+};
void ECS_Tick_Late(double delta) {
- for (long b = 0; b <= Comp_GrBinds_BucketContainer.bucketCounter; ++b) {
- auto &bkt = Comp_GrBinds_BucketContainer.buckets[b];
- long count = Comp_GrBinds_BucketContainer.bucketCounter == b ? Comp_GrBinds_BucketContainer.itemCounter >> 32 : maxBucketItemCount;
- for (long i = 0; i < count; ++i) {
- auto &grBinds = bkt.compGrBinds[i];
- if (grBinds.isInstanceBufferNeedingUpdated) {
- VkDeviceSize byteCount = sizeof(InstPos) * grBinds.instances.Count();
- VkBuffer transferBuffer;
- VkDeviceMemory transferMemory;
- void *deviceData;
- BeginTransferBuffer(byteCount, transferBuffer, transferMemory, deviceData);
- memcpy(deviceData, grBinds.instances.GetPtr(), byteCount);
- {
- VkCommandBufferBeginInfo cbbi;
- cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- cbbi.pNext = nullptr;
- cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- cbbi.pInheritanceInfo = nullptr;
-
- vkBeginCommandBuffer(transferCommandBuffer, &cbbi);
-
- VkBufferCopy vkBufferCopy;
- vkBufferCopy.srcOffset = 0;
- vkBufferCopy.dstOffset = 0;
- vkBufferCopy.size = byteCount;
-
- vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, grBinds.instanceBuffer, 1, &vkBufferCopy);
-
- vkEndCommandBuffer(transferCommandBuffer);
-
- VkSubmitInfo vkSubmitInfo{};
- vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- vkSubmitInfo.pNext = nullptr;
- vkSubmitInfo.waitSemaphoreCount = 0;
- vkSubmitInfo.pWaitSemaphores = nullptr;
- vkSubmitInfo.pWaitDstStageMask = nullptr;
- vkSubmitInfo.commandBufferCount = 1;
- vkSubmitInfo.pCommandBuffers = &transferCommandBuffer;
- vkSubmitInfo.signalSemaphoreCount = 0;
- vkSubmitInfo.pSignalSemaphores = nullptr;
- vkQueueSubmit(transferQueue, 1, &vkSubmitInfo, nullptr);
- vkQueueWaitIdle(transferQueue);
- vkResetCommandBuffer(transferCommandBuffer, 0);
+ DynArray<InstanceBufferCopy> bufferUpdates{0};
+ for (long b = 0; b <= Comp_Instance_BucketContainer.bucketCounter; ++b) {
+ auto &bkt = Comp_Instance_BucketContainer.buckets[b];
+ long count = Comp_Instance_BucketContainer.bucketCounter == b ? Comp_Instance_BucketContainer.itemCounter >> 32 : maxBucketItemCount;
+ for (uint32_t i = 0; i < count; ++i) {
+ auto &inst = bkt.instances[i];
+ if (inst.isNeedingUpdated == false)
+ continue;
+
+ GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(inst.grBindsHandle)};
+ auto b_inner = Buckets_GetBucketIndex(grBindsHandle_t);
+ auto bi_inner = Buckets_GetItemIndex(grBindsHandle_t);
+ auto &grBinds = Comp_GrBinds_BucketContainer.buckets[b_inner].compGrBinds[bi_inner];
+
+ InstanceBufferCopy *bfrUpdate = nullptr;
+ for (long u = 0; u < bufferUpdates.Count(); ++u) {
+ if (bufferUpdates[u].grBinds->grBindsHandle == inst.grBindsHandle) {
+ bfrUpdate = &bufferUpdates[u];
+ }
+ }
+ if (bfrUpdate == nullptr) {
+ bufferUpdates.Push({
+ .grBinds = &grBinds,
+ });
+ bfrUpdate = &bufferUpdates[bufferUpdates.Count() - 1];
+ }
+
+ InstanceBufferCopyChunk *chunk = nullptr;
+ for (long ii = 0; ii < bfrUpdate->chunks.Count(); ++ii) {
+ if (bfrUpdate->chunks[ii].endingIndex == inst.index - 1) {
+ chunk = &bfrUpdate->chunks[ii];
+ chunk->endingIndex += 1;
+ break;
}
- EndTransferBuffer(transferBuffer, transferMemory);
- grBinds.isInstanceBufferNeedingUpdated = false;
}
+ if (chunk == nullptr) {
+ bfrUpdate->chunks.Push({
+ .startingIndex = inst.index,
+ .endingIndex = inst.index,
+ });
+ chunk = &bfrUpdate->chunks[bfrUpdate->chunks.Count() - 1];
+ chunk->dstBufferCopy.dstOffset = sizeof(glm::mat4) * inst.index;
+ }
+
+ chunk->mats.Push(
+ glm::translate(glm::mat4(1), inst.instPos.pos)
+ * glm::mat4_cast(inst.instPos.rot)
+ * glm::scale(glm::mat4(1), inst.instPos.scale));
+ bfrUpdate->runningSize += sizeof(glm::mat4);
+ inst.isNeedingUpdated = false;
+ }
+ }
+ while (bufferUpdates.Count() > 0) {
+ InstanceBufferCopy ibc = bufferUpdates.Pop();
+
+ VkDeviceSize instanceBytes = sizeof(glm::mat4);
+ VkDeviceSize byteCount = ibc.runningSize;
+ VkBuffer transferBuffer;
+ VkDeviceMemory transferMemory;
+ void *deviceData;
+ BeginTransferBuffer(byteCount, transferBuffer, transferMemory, deviceData);
+ VkDeviceSize runningOffset = 0;
+ for (long i = 0; i < ibc.chunks.Count(); ++i) {
+ auto *chunk = &ibc.chunks[i];
+ memcpy(static_cast<char *>(deviceData) + runningOffset, chunk->mats.GetPtr(), byteCount);
+ chunk->dstBufferCopy.srcOffset = runningOffset;
+ chunk->dstBufferCopy.size = instanceBytes * (chunk->endingIndex - chunk->startingIndex + 1);
+ runningOffset += chunk->dstBufferCopy.size;
+ }
+ assert(runningOffset == ibc.runningSize);
+
+ {
+ VkCommandBufferBeginInfo cbbi;
+ cbbi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ cbbi.pNext = nullptr;
+ cbbi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ cbbi.pInheritanceInfo = nullptr;
+
+ vkBeginCommandBuffer(transferCommandBuffer, &cbbi);
+
+ for (long i = 0; i < ibc.chunks.Count(); ++i) {
+ vkCmdCopyBuffer(transferCommandBuffer, transferBuffer, ibc.grBinds->instanceBuffer, 1, &ibc.chunks[i].dstBufferCopy);
+ }
+
+ vkEndCommandBuffer(transferCommandBuffer);
+
+ VkSubmitInfo vkSubmitInfo{};
+ vkSubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ vkSubmitInfo.pNext = nullptr;
+ vkSubmitInfo.waitSemaphoreCount = 0;
+ vkSubmitInfo.pWaitSemaphores = nullptr;
+ vkSubmitInfo.pWaitDstStageMask = nullptr;
+ vkSubmitInfo.commandBufferCount = 1;
+ vkSubmitInfo.pCommandBuffers = &transferCommandBuffer;
+ vkSubmitInfo.signalSemaphoreCount = 0;
+ vkSubmitInfo.pSignalSemaphores = nullptr;
+ vkQueueSubmit(transferQueue, 1, &vkSubmitInfo, nullptr);
+ vkQueueWaitIdle(transferQueue);
+ vkResetCommandBuffer(transferCommandBuffer, 0);
}
+ EndTransferBuffer(transferBuffer, transferMemory);
}
}
@@ -261,25 +326,24 @@ CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityType
ent->instanceHandle = InstanceHandle{newHandle};
GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(entTypeEnt->grBindsHandle)};
- auto b2 = Buckets_GetBucketIndex(grBindsHandle_t);
- auto i2 = Buckets_GetItemIndex(grBindsHandle_t);
- auto *grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2];
- grBinds->isInstanceBufferNeedingUpdated = true;
- grBinds->instanceBindingCount = 1;
auto b = Buckets_GetBucketIndex(newHandle);
auto i = Buckets_GetItemIndex(newHandle);
- auto *comp = &Comp_Instance_BucketContainer.buckets[b].instances[i];
+ auto *instBkt = &Comp_Instance_BucketContainer.buckets[b];
+ auto *comp = &instBkt->instances[i];
comp = new (comp) CompInstance{};
comp->entHandle = entHandle;
+
+ auto b2 = Buckets_GetBucketIndex(grBindsHandle_t);
+ auto i2 = Buckets_GetItemIndex(grBindsHandle_t);
+ auto *grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2];
+
comp->grBindsHandle = grBinds->grBindsHandle;
comp->instanceHandle = ent->instanceHandle;
- comp->index = grBinds->instances.Count();
- grBinds->instances.Push({
- .pos = glm::vec3(0),
- .rot = glm::vec3(1),
- .scale = glm::vec3(1),
- });
- comp->ptr = &grBinds->instances[comp->index];
+ comp->index = grBinds->instanceCounter++;
+ comp->instPos.pos = glm::vec3(0, 0, 0);
+ comp->instPos.rot = glm::quat(1, 0, 0, 0);
+ comp->instPos.scale = glm::vec3(1, 1, 1);
+ comp->isNeedingUpdated = true;
return *comp;
}
@@ -295,16 +359,23 @@ CompInstance *ECS_GetInstance(EntityHandle entHandle) {
auto i = Buckets_GetItemIndex(instanceHandle_t);
auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i];
- if (inst->index == ECS_UNSET_VAL)
- return nullptr;
- if (inst->grBindsHandle == GrBindsHandle_MAX)
- return nullptr;
+ return inst;
+}
- GrBindsHandle_T grBindsHandle_t{static_cast<GrBindsHandle_T>(inst->grBindsHandle)};
- auto b2 = Buckets_GetBucketIndex(grBindsHandle_t);
- auto i2 = Buckets_GetItemIndex(grBindsHandle_t);
- auto grBinds = &Comp_GrBinds_BucketContainer.buckets[b2].compGrBinds[i2];
+void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos) {
+ Entity *ent = nullptr;
+ ECS_GetEntity_Inner(entHandle, ent);
- inst->ptr = &grBinds->instances[inst->index];
- return inst;
+ if (ent->instanceHandle == InstanceHandle_MAX)
+ return;
+
+ InstanceHandle_T instanceHandle_t{static_cast<InstanceHandle_T>(ent->instanceHandle)};
+ auto b = Buckets_GetBucketIndex(instanceHandle_t);
+ auto i = Buckets_GetItemIndex(instanceHandle_t);
+ auto *inst = &Comp_Instance_BucketContainer.buckets[b].instances[i];
+
+ inst->instPos.pos = instPos.pos;
+ inst->instPos.rot = instPos.rot;
+ inst->instPos.scale = instPos.scale;
+ inst->isNeedingUpdated = true;
}
diff --git a/src/ecs.hpp b/src/ecs.hpp
index 6293bc9..685dd81 100644
--- a/src/ecs.hpp
+++ b/src/ecs.hpp
@@ -5,7 +5,6 @@
#include "macros.hpp"
#include "memory.hpp"
#include "components.hpp"
-#include "window.hpp"
#include "glm/vec3.hpp"
@@ -14,6 +13,7 @@ extern DynArray<EntityHandle> EntitiesToBeRemoved;
static struct {
uint64_t Entity = 1ULL << 0;
uint64_t GrBinds = 1ULL << 1;
+ uint64_t Instance = 1ULL << 2;
} ComponentTypes;
void ECS_Init();
@@ -31,5 +31,6 @@ CompGrBinds *ECS_GetGrBinds(uint64_t bucketIndex, uint64_t &itemCount);
CompInstance &ECS_CreateInstance(EntityHandle entHandle, EntityHandle entityTypeEntityHandle);
CompInstance *ECS_GetInstance(EntityHandle entHandle);
+void ECS_UpdateInstance(EntityHandle entHandle, const InstPos &instPos);
#endif /* PKE_ECS_HPP */
diff --git a/src/entities.cpp b/src/entities.cpp
index 7263bbd..fd55970 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -97,11 +97,10 @@ void EntityType_Init() {
// index += 1;
// instance
vertInputBD[index].binding = index;
- vertInputBD[index].stride = sizeof(glm::vec3) * 3;
+ vertInputBD[index].stride = sizeof(glm::mat4);
vertInputBD[index].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
- const long vertexAttrDescCount = 6;
- long runningOffset = 0;
+ const long vertexAttrDescCount = 7;
index = 0;
VkVertexInputAttributeDescription vertAttrDesc[vertexAttrDescCount];
for (long i = 0; i < vertexAttrDescCount; ++i) {
@@ -111,44 +110,28 @@ void EntityType_Init() {
// model vertex
vertAttrDesc[index].binding = 0;
vertAttrDesc[index].format = VK_FORMAT_R32G32B32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- runningOffset += sizeof(glm::vec3);
+ vertAttrDesc[index].offset = 0;
index += 1;
// model normals
vertAttrDesc[index].binding = 1;
vertAttrDesc[index].format = VK_FORMAT_R32G32B32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- runningOffset += sizeof(glm::vec3);
+ vertAttrDesc[index].offset = 0;
index += 1;
// model UV
vertAttrDesc[index].binding = 2;
vertAttrDesc[index].format = VK_FORMAT_R32G32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- runningOffset += sizeof(glm::vec2);
+ vertAttrDesc[index].offset = 0;
index += 1;
- // instance pos
- vertAttrDesc[index].binding = 3;
- vertAttrDesc[index].format = VK_FORMAT_R32G32B32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- runningOffset += sizeof(glm::vec3);
- index += 1;
-
- // instance rot
- vertAttrDesc[index].binding = 3;
- vertAttrDesc[index].format = VK_FORMAT_R32G32B32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- runningOffset += sizeof(glm::vec3);
- index += 1;
-
- // instance scale
- vertAttrDesc[index].binding = 3;
- vertAttrDesc[index].format = VK_FORMAT_R32G32B32_SFLOAT;
- vertAttrDesc[index].offset = runningOffset;
- // runningOffset += sizeof(glm::vec3);
- // index += 1;
+ // instPosRotScale
+ for (long i = 0; i < 4; ++i) {
+ vertAttrDesc[index].binding = 3;
+ vertAttrDesc[index].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+ vertAttrDesc[index].offset = sizeof(glm::vec4) * i;
+ index += 1;
+ }
// instance texture index
// vertAttrDesc[index].binding = 3;
@@ -717,6 +700,7 @@ void EntityType_Load(EntityType &et) {
// 2023-09-27 - JCB
// I don't know where else to put this
grBinds.instanceFirstBinding = index;
+ grBinds.instanceBindingCount = 1;
// no index += 1 because index just happens to be the right value here for
// the binding index, whereas binding the IndexBuffer doesn't need a binding index.
diff --git a/src/game.cpp b/src/game.cpp
index d95e43b..071a2b3 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1,6 +1,7 @@
#include "game.hpp"
-#include "memory.hpp"
+
+#include "vendor/glm_include.hpp"
#include <cstring>
@@ -213,6 +214,10 @@ void Game_Tick(double delta) {
EntityHandle newEntity = ECS_CreateEntity();
ECS_CreateInstance(newEntity, createInfo.entityTypeEntityHandle);
}
+ static double accDelta = 0.0;
+ accDelta += delta;
+ UBO.model = glm::rotate(glm::mat4(1.0f), (float)accDelta * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
+ UBO.view = glm::lookAt(glm::vec3(4.0f, 4.0f, 4.0f), glm::vec3(0), glm::vec3(0.0f, 0.0f, 1.0f));
ECS_Tick_Late(delta);
}
@@ -439,8 +444,7 @@ void RecordImGui_CompGrBinds(bool readonly, CompGrBinds *component) {
ImGui::InputScalar("InstanceBindingCount", ImGuiDataType_U32, &component->instanceBindingCount, nullptr, nullptr, nullptr, inputTextFlags);
ImGui::InputScalar("InstanceOffsets", ImGuiDataType_U64, &component->instanceOffsets, nullptr, nullptr, nullptr, inputTextFlags);
- int64_t count = component->instances.Count();
- ImGui::InputScalar("Instance Count", ImGuiDataType_S64, &count, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly);
+ ImGui::InputScalar("Instance Count", ImGuiDataType_S64, &component->instanceCounter, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly);
ImGui::Spacing();
}
@@ -454,11 +458,15 @@ void RecordImGui_CompInstPos(bool readonly, CompInstance *component) {
ImGui::Text("CompInststance + InstPos");
ImGui::Separator();
- ImGui::InputScalar("Instance Index", ImGuiDataType_U64, &component->index, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly);
- if (component->ptr) {
- ImGui::InputScalarN("pos", ImGuiDataType_Float, &component->ptr->pos, 3, nullptr, nullptr, nullptr, inputTextFlags);
- ImGui::InputScalarN("rot", ImGuiDataType_Float, &component->ptr->rot, 3, nullptr, nullptr, nullptr, inputTextFlags);
- ImGui::InputScalarN("scale", ImGuiDataType_Float, &component->ptr->scale, 3, nullptr, nullptr, nullptr, inputTextFlags);
+ bool changed = false;
+
+ changed = ImGui::InputScalar("Instance Index", ImGuiDataType_U64, &component->index, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly) || changed;
+ changed = ImGui::InputScalarN("pos", ImGuiDataType_Float, &component->instPos.pos, 3, nullptr, nullptr, nullptr, inputTextFlags) || changed;
+ changed = ImGui::InputScalarN("rot", ImGuiDataType_Float, &component->instPos.rot, 4, nullptr, nullptr, nullptr, inputTextFlags) || changed;
+ changed = ImGui::InputScalarN("scale", ImGuiDataType_Float, &component->instPos.scale, 3, nullptr, nullptr, nullptr, inputTextFlags) || changed;
+
+ if (changed) {
+ ECS_UpdateInstance(component->entHandle, component->instPos);
}
ImGui::Spacing();
diff --git a/src/window.cpp b/src/window.cpp
index d4ac37b..1a9a584 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1374,7 +1374,7 @@ void RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
vkCmdBindVertexBuffers(commandBuffer, binder->uvFirstBinding, binder->uvBindingCount, &binder->uvBuffer, &binder->uvOffsets);
vkCmdBindVertexBuffers(commandBuffer, binder->instanceFirstBinding, binder->instanceBindingCount, &binder->instanceBuffer, &binder->instanceOffsets);
- vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instances.Count(), 0, 0, 0);
+ vkCmdDrawIndexed(commandBuffer, binder->indexCount, binder->instanceCounter, 0, 0, 0);
}
}