Hi! I’ve an issue and it’s been several days now I don’t understand why. Everything worked perfectly until I added a new buffer for object model matrices in addition of instances model matrices.
I’ve always the same vertex attrribute values in the vertex shader here (and only on this vertex shader it works for the others) :
const std::string perPixReflectRefractIndirectRenderingVertexShader = R"(#version 460
#extension GL_EXT_debug_printf : enable
layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;
layout (location = 2) in vec2 texCoords;
layout (location = 3) in vec3 normals;
layout (location = 4) in int drawableDataID;
layout (push_constant)uniform PushConsts {
mat4 projectionMatrix;
layout (offset = 64) mat4 viewMatrix;
} pushConsts;
struct ModelData {
mat4 modelMatrix;
};
struct MaterialData {
vec2 uvScale;
vec2 uvOffset;
uint textureIndex;
uint layer;
uint materialType;
uint instanced;
};
layout(set = 0, binding = 2) buffer modelData {
ModelData modelDatas[];
};
layout(set = 0, binding = 3) buffer materialData {
MaterialData materialDatas[];
};
layout(set = 0, binding = 4) buffer objectData {
ModelData objectDatas[];
};
layout (location = 0) out vec3 pos;
layout (location = 1) out vec4 frontColor;
layout (location = 2) out vec2 texCoord;
layout (location = 3) out uint materialType;
layout (location = 4) out vec3 normal;
layout (location = 5) out int drawableID;
void main () {
gl_PointSize = 2.0f;
MaterialData material = materialDatas[gl_DrawID];
ModelData model = modelDatas[gl_InstanceIndex];
ModelData object = objectDatas[drawableDataID];
mat4 modelMatrix = /*(material.instanced == 1) ?*/ model.modelMatrix /*: object.modelMatrix*/;
if (drawableDataID != 0)
debugPrintfEXT("drawable id : %i", drawableDataID);
/*if (material.instanced == 0)
debugPrintfEXT("Object model matrix : %v4f\n%v4f\n%v4f\n%v4f", modelMatrix[0], modelMatrix[1], modelMatrix[2], modelMatrix[3]);*/
uint materialT = material.materialType;
pos = vec3(vec4(position, 1.0) * modelMatrix);
gl_Position = vec4(position, 1.f) * modelMatrix * pushConsts.viewMatrix * pushConsts.projectionMatrix;
frontColor = color;
texCoord = texCoords * material.uvScale + material.uvOffset;
normal = mat3(transpose(inverse(modelMatrix))) * normals;
materialType = materialT;
drawableID = drawableDataID;
//debugPrintfEXT("vertex position : %v4f", gl_Position);
}
)";
drawableDataID is always 0, I don’t know why. When I add the vertices to my vertex buffer the values are correct at CPU side here :
unsigned int vertexCount = 0, indexCount = 0;
if (m_reflNormalIndexed[i].getEntities().size() > 0){
for (unsigned int j = 0; j < m_reflNormalIndexed[i].getEntities().size(); j++) {
Entity* entity = m_reflNormalIndexed[i].getEntities()[j]->getRootEntity();
if (entity == reflectEntity) {
for (unsigned int f = 0; f < m_reflNormalIndexed[i].getEntities()[j]->getFaces().size(); f++) {
for (unsigned int k = 0; k < m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray().getVertexCount(); k++) {
vertexCount++;
/*math::Vec3f t = m_reflNormalIndexed[i].getEntities()[j]->getTransform().transform(math::Vec4f(m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k].position));
Vertex v (t, m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k].color, m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k].texCoords);
v.normal = m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k].normal;*/
//std::cout<<"padding : "<<m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k].drawableDataID<<std::endl;
vbBindlessTexIndexed[p].append(m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray()[k]);
}
for (unsigned int k = 0; k < m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray().getIndexes().size(); k++) {
////std::cout<<"add refl norm indexed"<<std::endl;
indexCount++;
vbBindlessTexIndexed[p].addIndex(m_reflNormalIndexed[i].getEntities()[j]->getFace(f)->getVertexArray().getIndexes()[k]);
}
}
}
}
}
It’s been I added the objectDataBufferMT buffers I have that strange issue. I update my vertex buffer here :
for (unsigned int p = 0; p < Batcher::nbPrimitiveTypes; p++) {
if (vbBindlessTex[p].getVertexCount() > 0)
vbBindlessTex[p].updateBuffers(currentFrame);
if (vbBindlessTexIndexed[p].getVertexCount() > 0)
vbBindlessTexIndexed[p].updateBuffers(currentFrame);
}
.....
bufferSize = sizeof(ModelData) * objectDatas[p].size();
if (bufferSize > 0)
copyBuffer(objectDataStagingBufferMT[p][currentFrame], objectDataBufferMT[p][currentFrame], bufferSize, copyObjectDataBufferCommandBuffer[currentFrame]);
bufferSize = sizeof(MaterialData) * materialDatas[p].size();
if (bufferSize > 0)
copyBuffer(materialDataStagingBufferMT[p][currentFrame],materialDataBufferMT[p][currentFrame], bufferSize, copyMaterialDataBufferCommandBuffer[currentFrame]);
bufferSize = sizeof(DrawArraysIndirectCommand) * drawArraysIndirectCommands[p].size();
if (bufferSize > 0)
copyBuffer(vboIndirectStagingBufferMT[p][currentFrame], drawCommandBufferMT[p][currentFrame], totalBufferSizeDrawCommand[p], copyDrawBufferCommandBuffer[currentFrame]);
bufferSize = sizeof(DrawElementsIndirectCommand) * drawElementsIndirectCommands[p].size();
if (bufferSize > 0)
copyBuffer(vboIndexedIndirectStagingBufferMT[p][currentFrame], drawCommandBufferIndexedMT[p][currentFrame], bufferSize, copyDrawIndexedBufferCommandBuffer[currentFrame]);
if (vbBindlessTex[p].getVertexCount() > 0)
vbBindlessTex[p].registerCopyCmdBuffers(currentFrame, copyVbBufferCommandBuffer[currentFrame]);
if (vbBindlessTexIndexed[p].getVertexCount() > 0)
vbBindlessTexIndexed[p].registerCopyCmdBuffers(currentFrame, copyVbIndexedBufferCommandBuffer[currentFrame]);
}
....
Here is my vertex buffer class :
#include "../../../include/odfaeg/Graphics/vertexBuffer.hpp"
#include "../../../include/odfaeg/Graphics/renderTarget.h"
#ifndef VULKAN
#include "GL/glew.h"
#include <ODFAEG/OpenGL.hpp>
#include "glCheck.h"
#endif
#include <string.h>
namespace odfaeg {
namespace graphic {
#ifdef VULKAN
VertexBuffer::VertexBuffer(window::Device& vkDevice) : vkDevice(vkDevice), m_primitiveType(Points) {
createCommandPool();
}
/*VertexBuffer::VertexBuffer(const VertexBuffer& vb) : vkDevice(vb.vkDevice) {
createCommandPool();
m_vertices = vb.m_vertices;
indices = vb.indices;
needToUpdateVertexBuffer = (m_vertices.size() > 0) ? true : false;
needToUpdateIndexBuffer = (indices.size() > 0) ? true : false;
update();
}*/
VertexBuffer::VertexBuffer(VertexBuffer&& vb) :
vkDevice(vb.vkDevice)
{
// Transfert des ressources
createCommandPool();
m_vertices = std::move(vb.m_vertices);
indices = std::move(vb.indices);
needToUpdateIndexBuffer = {!indices.empty(), !indices.empty()};
needToUpdateVertexBuffer = {!m_vertices.empty(), !m_vertices.empty()};
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vertexBuffer[i] = std::exchange(vb.vertexBuffer[i], VK_NULL_HANDLE);
indexBuffer[i] = std::exchange(vb.indexBuffer[i], VK_NULL_HANDLE);
vertexBufferMemory[i] = std::exchange(vb.vertexBufferMemory[i], VK_NULL_HANDLE);
indexBufferMemory[i] = std::exchange(vb.indexBufferMemory[i], VK_NULL_HANDLE);
}
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vertexStagingBuffer[i] = std::exchange(vb.vertexStagingBuffer[i], VK_NULL_HANDLE);
vertexStagingBufferMemory[i] = std::exchange(vb.vertexStagingBufferMemory[i], VK_NULL_HANDLE);
indexStagingBuffer[i] = std::exchange(vb.indexStagingBuffer[i], VK_NULL_HANDLE);
indexStagingBufferMemory[i] = std::exchange(vb.indexStagingBufferMemory[i], VK_NULL_HANDLE);
}
maxVerticesSize = vb.maxVerticesSize;
maxIndexSize = vb.maxIndexSize;
}
/*VertexBuffer& VertexBuffer::operator=(const VertexBuffer& vb) {
commandPool = vb.commandPool;
m_vertices = vb.m_vertices;
indices = vb.indices;
needToUpdateVertexBuffer = (m_vertices.size() > 0) ? true : false;
needToUpdateIndexBuffer = (indices.size() > 0) ? true : false;
update();
return *this;
}*/
VertexBuffer& VertexBuffer::operator=(VertexBuffer&& vb) {
if (this != &vb) {
// Libérer les ressources actuelles si nécessaire
//cleanup(); // méthode qui détruit vertexBuffer, indexBuffer, etc.
// Transfert des ressources
commandPool = vb.commandPool;
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vertexBuffer[i] = std::exchange(vb.vertexBuffer[i], VK_NULL_HANDLE);
indexBuffer[i] = std::exchange(vb.indexBuffer[i], VK_NULL_HANDLE);
vertexBufferMemory[i] = std::exchange(vb.vertexBufferMemory[i], VK_NULL_HANDLE);
indexBufferMemory[i] = std::exchange(vb.indexBufferMemory[i], VK_NULL_HANDLE);
}
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vertexStagingBuffer[i] = std::exchange(vb.vertexStagingBuffer[i], VK_NULL_HANDLE);
vertexStagingBufferMemory[i] = std::exchange(vb.vertexStagingBufferMemory[i], VK_NULL_HANDLE);
indexStagingBuffer[i] = std::exchange(vb.indexStagingBuffer[i], VK_NULL_HANDLE);
indexStagingBufferMemory[i] = std::exchange(vb.indexStagingBufferMemory[i], VK_NULL_HANDLE);
}
m_vertices = std::move(vb.m_vertices);
indices = std::move(vb.indices);
needToUpdateIndexBuffer = {!indices.empty(), !indices.empty()};
needToUpdateVertexBuffer = {!m_vertices.empty(), !m_vertices.empty()};
maxVerticesSize = vb.maxVerticesSize;
maxIndexSize = vb.maxIndexSize;
//update(); // maintenant que les ressources sont valides
}
return *this;
}
void VertexBuffer::clear() {
m_vertices.clear();
indices.clear();
}
void VertexBuffer::clearIndexes() {
indices.clear();
}
void VertexBuffer::addIndex(uint32_t index) {
indices.push_back(index);
needToUpdateIndexBuffer = {true, true};
}
void VertexBuffer::append(const Vertex& vertex) {
m_vertices.push_back(vertex);
needToUpdateVertexBuffer = {true, true};
}
void VertexBuffer::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) {
window::Device::QueueFamilyIndices queueFamilyIndices = vkDevice.findQueueFamilies(vkDevice.getPhysicalDevice(), VK_NULL_HANDLE);
uint32_t queueIndices[] = { queueFamilyIndices.computeFamily.value(), queueFamilyIndices.graphicsFamily.value() };
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = usage;
bufferInfo.sharingMode = VK_SHARING_MODE_CONCURRENT;
bufferInfo.queueFamilyIndexCount = 2;
bufferInfo.pQueueFamilyIndices = queueIndices;
if (vkCreateBuffer(vkDevice.getDevice(), &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
throw std::runtime_error("failed to create buffer!");
}
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(vkDevice.getDevice(), buffer, &memRequirements);
VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
if (vkAllocateMemory(vkDevice.getDevice(), &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
throw std::runtime_error("failed to allocate buffer memory!");
}
vkBindBufferMemory(vkDevice.getDevice(), buffer, bufferMemory, 0);
}
void VertexBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size, VkCommandBuffer cmd) {
if (srcBuffer != nullptr && dstBuffer != nullptr && size > 0) {
VkBufferCopy copyRegion{};
copyRegion.size = size;
vkCmdCopyBuffer(cmd, srcBuffer, dstBuffer, 1, ©Region);
}
}
void VertexBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) {
VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = commandPool;
allocInfo.commandBufferCount = 1;
VkCommandBuffer commandBuffer;
vkAllocateCommandBuffers(vkDevice.getDevice(), &allocInfo, &commandBuffer);
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
vkBeginCommandBuffer(commandBuffer, &beginInfo);
if (srcBuffer != nullptr && dstBuffer != nullptr && size > 0) {
VkBufferCopy copyRegion{};
copyRegion.size = size;
vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region);
}
vkEndCommandBuffer(commandBuffer);
VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
window::Device::QueueFamilyIndices indices = vkDevice.findQueueFamilies(vkDevice.getPhysicalDevice(), nullptr);
vkQueueSubmit(vkDevice.getQueue(indices.graphicsFamily.value(), 0), 1, &submitInfo, VK_NULL_HANDLE);
vkQueueWaitIdle(vkDevice.getQueue(indices.graphicsFamily.value(), 0));
vkFreeCommandBuffers(vkDevice.getDevice(), commandPool, 1, &commandBuffer);
}
uint32_t VertexBuffer::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) {
VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(vkDevice.getPhysicalDevice(), &memProperties);
for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
return i;
}
}
throw std::runtime_error("aucun type de memoire ne satisfait le buffer!");
}
VkBuffer VertexBuffer::getVertexBuffer(unsigned int currentFrame) {
return vertexBuffer[currentFrame];
}
size_t VertexBuffer::getSize() {
return m_vertices.size();
}
size_t VertexBuffer::getVertexCount() {
return m_vertices.size();
}
size_t VertexBuffer::getIndicesSize() {
return indices.size();
}
VkBuffer VertexBuffer::getIndexBuffer(unsigned int currentFrame) {
return indexBuffer[currentFrame];
}
////////////////////////////////////////////////////////////
void VertexBuffer::setPrimitiveType(PrimitiveType type)
{
m_primitiveType = type;
}
////////////////////////////////////////////////////////////
PrimitiveType VertexBuffer::getPrimitiveType() const
{
return m_primitiveType;
}
void VertexBuffer::update(unsigned int currentFrame, VkCommandBuffer cmd) {
VkDeviceSize bufferSize = sizeof(Vertex) * m_vertices.size();
if (needToUpdateVertexBuffer[currentFrame]) {
if (bufferSize > maxVerticesSize[currentFrame]) {
if (vertexStagingBuffer[currentFrame] != nullptr) {
vkDestroyBuffer(vkDevice.getDevice(), vertexStagingBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexStagingBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer[currentFrame], vertexStagingBufferMemory[currentFrame]);
if (vertexBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer[currentFrame], vertexBufferMemory[currentFrame]);
maxVerticesSize[currentFrame] = bufferSize;
}
needToUpdateVertexBuffer[currentFrame] = false;
////////std::cout<<"vertex buffer : "<<indexBuffer<<std::endl;
}
copyBuffer(vertexStagingBuffer[currentFrame], vertexBuffer[currentFrame], bufferSize, cmd);
bufferSize = sizeof(uint32_t) * indices.size();
if (needToUpdateIndexBuffer[currentFrame]) {
if (bufferSize > maxIndexSize[currentFrame]) {
if (indexStagingBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexStagingBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexStagingBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer[currentFrame], indexStagingBufferMemory[currentFrame]);
if (indexBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer[currentFrame], indexBufferMemory[currentFrame]);
maxIndexSize[currentFrame] = bufferSize;
}
needToUpdateIndexBuffer[currentFrame] = false;
////////std::cout<<"index buffer : "<<indexBuffer<<std::endl;
}
copyBuffer(indexStagingBuffer[currentFrame], indexBuffer[currentFrame], bufferSize, cmd);
}
void VertexBuffer::updateBuffers(unsigned int currentFrame) {
VkDeviceSize bufferSize = sizeof(Vertex) * m_vertices.size();
if (needToUpdateVertexBuffer[currentFrame]) {
if (bufferSize > maxVerticesSize[currentFrame]) {
if (vertexStagingBuffer[currentFrame] != nullptr) {
vkDestroyBuffer(vkDevice.getDevice(), vertexStagingBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexStagingBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer[currentFrame], vertexStagingBufferMemory[currentFrame]);
if (vertexBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer[currentFrame], vertexBufferMemory[currentFrame]);
//std::cout<<"vertex buffer created"<<std::endl;
}
maxVerticesSize[currentFrame] = bufferSize;
needToUpdateVertexBuffer[currentFrame] = false;
////////std::cout<<"vertex buffer : "<<indexBuffer<<std::endl;
}
bufferSize = sizeof(uint32_t) * indices.size();
if (needToUpdateIndexBuffer[currentFrame]) {
if (bufferSize > maxIndexSize[currentFrame]) {
if (indexStagingBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexStagingBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexStagingBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer[currentFrame], indexStagingBufferMemory[currentFrame]);
if (indexBuffer[currentFrame] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexBuffer[currentFrame], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexBufferMemory[currentFrame], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer[currentFrame], indexBufferMemory[currentFrame]);
}
maxIndexSize[currentFrame] = bufferSize;
needToUpdateIndexBuffer[currentFrame] = false;
////////std::cout<<"index buffer : "<<indexBuffer<<std::endl;
}
}
void VertexBuffer::registerCopyCmdBuffers(unsigned int currentFrame, VkCommandBuffer cmd) {
VkDeviceSize bufferSize = sizeof(Vertex) * m_vertices.size();
copyBuffer(vertexStagingBuffer[currentFrame], vertexBuffer[currentFrame], bufferSize, cmd);
bufferSize = sizeof(uint32_t) * indices.size();
copyBuffer(indexStagingBuffer[currentFrame], indexBuffer[currentFrame], bufferSize, cmd);
}
void VertexBuffer::updateStagingBuffers(unsigned int currentFrame) {
//if (needToUpdateVertexStagingBuffer) {
////std::cout<<"update vb sg"<<std::endl;
if (vertexStagingBufferMemory[currentFrame] != nullptr) {
VkDeviceSize bufferSize = sizeof(Vertex) * m_vertices.size();
if (bufferSize > 0) {
void* data;
vkMapMemory(vkDevice.getDevice(), vertexStagingBufferMemory[currentFrame], 0, bufferSize, 0, &data);
memcpy(data, m_vertices.data(), (size_t) bufferSize);
vkUnmapMemory(vkDevice.getDevice(), vertexStagingBufferMemory[currentFrame]);
}
}
if (indexStagingBufferMemory[currentFrame] != nullptr) {
VkDeviceSize bufferSize = sizeof(uint32_t) * indices.size();
if (bufferSize > 0) {
void* data;
vkMapMemory(vkDevice.getDevice(), indexStagingBufferMemory[currentFrame], 0, bufferSize, 0, &data);
memcpy(data, indices.data(), (size_t) bufferSize);
vkUnmapMemory(vkDevice.getDevice(), indexStagingBufferMemory[currentFrame]);
}
}
}
void VertexBuffer::update() {
VkDeviceSize bufferSize = sizeof(Vertex) * m_vertices.size();
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (needToUpdateVertexBuffer[i]) {
if (bufferSize > maxVerticesSize[i]) {
if (vertexStagingBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexStagingBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexStagingBufferMemory[i], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexStagingBuffer[i], vertexStagingBufferMemory[i]);
if (vertexBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexBufferMemory[i], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer[i], vertexBufferMemory[i]);
maxVerticesSize[i] = bufferSize;
}
}
needToUpdateVertexBuffer[i] = false;
}
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (vertexStagingBuffer[i] != VK_NULL_HANDLE && bufferSize > 0) {
//std::cout<<"update"<<std::endl;
void* data;
vkMapMemory(vkDevice.getDevice(), vertexStagingBufferMemory[i], 0, bufferSize, 0, &data);
memcpy(data, m_vertices.data(), (size_t) bufferSize);
vkUnmapMemory(vkDevice.getDevice(), vertexStagingBufferMemory[i]);
}
copyBuffer(vertexStagingBuffer[i], vertexBuffer[i], bufferSize);
}
bufferSize = sizeof(uint32_t) * indices.size();
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (needToUpdateIndexBuffer[i]) {
if (bufferSize > maxIndexSize[i]) {
if (indexStagingBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexStagingBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexStagingBufferMemory[i], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexStagingBuffer[i], indexStagingBufferMemory[i]);
if (indexBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexBufferMemory[i], nullptr);
}
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer[i], indexBufferMemory[i]);
maxIndexSize[i] = bufferSize;
}
}
needToUpdateIndexBuffer[i] = false;
}
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (indexStagingBuffer[i] != VK_NULL_HANDLE && bufferSize > 0) {
void* data;
vkMapMemory(vkDevice.getDevice(), indexStagingBufferMemory[i], 0, bufferSize, 0, &data);
memcpy(data, indices.data(), (size_t) bufferSize);
vkUnmapMemory(vkDevice.getDevice(), indexStagingBufferMemory[i]);
}
copyBuffer(indexStagingBuffer[i], indexBuffer[i], bufferSize);
}
}
Vertex& VertexBuffer::operator [](unsigned int index)
{
return m_vertices[index];
}
void VertexBuffer::createCommandPool() {
window::Device::QueueFamilyIndices queueFamilyIndices = vkDevice.findQueueFamilies(vkDevice.getPhysicalDevice(), VK_NULL_HANDLE);
VkCommandPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value();
poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; // Optionel
if (vkCreateCommandPool(vkDevice.getDevice(), &poolInfo, nullptr, &commandPool) != VK_SUCCESS) {
throw core::Erreur(0, "échec de la création d'une command pool!", 1);
}
}
void VertexBuffer::draw(RenderTarget& target, RenderStates states) {
target.drawVertexBuffer(*this, states);
}
void VertexBuffer::reserve(unsigned int size) {
m_vertices.reserve(size);
}
void VertexBuffer::reserveIdx(unsigned int size) {
indices.reserve(size);
}
void VertexBuffer::cleanup() {
vkDestroyCommandPool(vkDevice.getDevice(), commandPool, nullptr);
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (vertexBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexBufferMemory[i], nullptr);
}
if (vertexStagingBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), vertexStagingBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), vertexStagingBufferMemory[i], nullptr);
}
}
for (unsigned int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (indexBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexBufferMemory[i], nullptr);
}
if (indexStagingBuffer[i] != VK_NULL_HANDLE) {
vkDestroyBuffer(vkDevice.getDevice(), indexStagingBuffer[i], nullptr);
vkFreeMemory(vkDevice.getDevice(), indexStagingBufferMemory[i], nullptr);
}
}
}
VertexBuffer::~VertexBuffer() {
cleanup();
}
#else
////////////////////////////////////////////////////////////
VertexBuffer::VertexBuffer() :
m_vertices (),
m_primitiveType(Points),
m_entity(nullptr)
{
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
vboTextureIndexesBuffer = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
needToUpdateVertexBuffer = false;
needToUpdateIndexBuffer = false;
needToUpdateLayersBuffer = false;
needToUpdateMaterialTypeBuffer = false;
needToUpdateSpecularBuffer = false;
needToUpdateLightInfos = false;
needToUpdateNormals = false;
nbVerticesPerFace = 4;
loop = true;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
}
VertexBuffer::VertexBuffer(const VertexBuffer& va) {
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
vboTextureIndexesBuffer = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
m_entity = va.m_entity;
m_normals = va.m_normals;
m_locals = va.m_locals;
m_vertices = va.m_vertices;
m_layers = va.m_layers;
m_specular = va.m_specular;
m_primitiveType = va.m_primitiveType;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
m_numIndexes = va.m_numIndexes;
m_baseIndexes = va.m_baseIndexes;
m_baseVertices = va.m_baseVertices;
m_indexes = va.m_indexes;
m_layers = va.m_layers;
m_lightInfos = va.m_lightInfos;
loop = va.loop;
m_vPosX = va.m_vPosX;
m_vPosY = va.m_vPosY;
m_vPosZ = va.m_vPosZ;
m_vPosW = va.m_vPosW;
m_vcRed = va.m_vcRed;
m_vcGreen = va.m_vcGreen;
m_vcBlue = va.m_vcBlue;
m_vcAlpha = va.m_vcAlpha;
m_ctX = va.m_ctX;
m_ctY = va.m_ctY;
nbVerticesPerFace = va.nbVerticesPerFace;
needToUpdateVertexBuffer = true;
needToUpdateIndexBuffer = true;
needToUpdateMaterialTypeBuffer = true;
needToUpdateLayersBuffer = true;
needToUpdateSpecularBuffer = true;
needToUpdateLightInfos = true;
needToUpdateNormals = true;
}
VertexBuffer::VertexBuffer(const VertexBuffer&& va) {
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
vboTextureIndexesBuffer = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
m_entity = va.m_entity;
m_normals = va.m_normals;
m_locals = va.m_locals;
m_vertices = va.m_vertices;
m_primitiveType = va.m_primitiveType;
m_layers = va.m_layers;
m_specular = va.m_specular;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
m_numIndexes = va.m_numIndexes;
m_baseIndexes = va.m_baseIndexes;
m_baseVertices = va.m_baseVertices;
m_indexes = va.m_indexes;
m_lightInfos = va.m_lightInfos;
loop = va.loop;
m_vPosX = va.m_vPosX;
m_vPosY = va.m_vPosY;
m_vPosZ = va.m_vPosZ;
m_vPosW = va.m_vPosW;
m_vcRed = va.m_vcRed;
m_vcGreen = va.m_vcGreen;
m_vcBlue = va.m_vcBlue;
m_vcAlpha = va.m_vcAlpha;
m_ctX = va.m_ctX;
m_ctY = va.m_ctY;
nbVerticesPerFace = va.nbVerticesPerFace;
needToUpdateVertexBuffer = true;
needToUpdateIndexBuffer = true;
needToUpdateMaterialTypeBuffer = true;
needToUpdateLayersBuffer = true;
needToUpdateSpecularBuffer = true;
needToUpdateLightInfos = true;
needToUpdateNormals = true;
}
VertexBuffer& VertexBuffer::operator= (const VertexBuffer& va) {
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
vboTextureIndexesBuffer = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
m_entity = va.m_entity;
m_normals = va.m_normals;
m_locals = va.m_locals;
m_vertices = va.m_vertices;
m_layers = va.m_layers;
m_specular = va.m_specular;
m_primitiveType = va.m_primitiveType;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
m_numIndexes = va.m_numIndexes;
m_baseIndexes = va.m_baseIndexes;
m_baseVertices = va.m_baseVertices;
m_indexes = va.m_indexes;
m_lightInfos = va.m_lightInfos;
loop = va.loop;
m_vPosX = va.m_vPosX;
m_vPosY = va.m_vPosY;
m_vPosZ = va.m_vPosZ;
m_vPosW = va.m_vPosW;
m_vcRed = va.m_vcRed;
m_vcGreen = va.m_vcGreen;
m_vcBlue = va.m_vcBlue;
m_vcAlpha = va.m_vcAlpha;
m_ctX = va.m_ctX;
m_ctY = va.m_ctY;
nbVerticesPerFace = va.nbVerticesPerFace;
needToUpdateVertexBuffer = true;
needToUpdateIndexBuffer = true;
needToUpdateMaterialTypeBuffer = true;
needToUpdateLayersBuffer = true;
needToUpdateSpecularBuffer = true;
needToUpdateLightInfos = true;
needToUpdateNormals = true;
return *this;
}
VertexBuffer& VertexBuffer::operator= (const VertexBuffer&& va) {
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
vboTextureIndexesBuffer = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
m_entity = va.m_entity;
m_normals = va.m_normals;
m_locals = va.m_locals;
m_vertices = va.m_vertices;
m_layers = va.m_layers;
m_specular = va.m_specular;
m_primitiveType = va.m_primitiveType;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
m_numIndexes = va.m_numIndexes;
m_baseIndexes = va.m_baseIndexes;
m_baseVertices = va.m_baseVertices;
m_indexes = va.m_indexes;
m_lightInfos = va.m_lightInfos;
loop = va.loop;
m_vPosX = va.m_vPosX;
m_vPosY = va.m_vPosY;
m_vPosZ = va.m_vPosZ;
m_vPosW = va.m_vPosW;
m_vcRed = va.m_vcRed;
m_vcGreen = va.m_vcGreen;
m_vcBlue = va.m_vcBlue;
m_vcAlpha = va.m_vcAlpha;
m_ctX = va.m_ctX;
m_ctY = va.m_ctY;
nbVerticesPerFace = va.nbVerticesPerFace;
needToUpdateVertexBuffer = true;
needToUpdateIndexBuffer = true;
needToUpdateMaterialTypeBuffer = true;
needToUpdateLayersBuffer = true;
needToUpdateSpecularBuffer = true;
needToUpdateLightInfos = true;
needToUpdateNormals = true;
return *this;
}
void VertexBuffer::addNormal(math::Vec3f normal) {
m_normals.push_back(normal);
}
void VertexBuffer::computeNormals() {
/*if (needToUpdateNormals) {
unsigned int size = 0;
if (m_primitiveType == PrimitiveType::Quads) {
size = m_vertices.size() / 4;
} else if (m_primitiveType == PrimitiveType::Triangles) {
size = m_vertices.size() / 3;
} else if (m_primitiveType == PrimitiveType::TriangleStrip || m_primitiveType == PrimitiveType::TriangleFan) {
size = (m_vertices.size() > 2) ? m_vertices.size() - 2 : 0;
}
m_normals.resize(m_vertices.size());
for (unsigned int i = 0; i < size; i++) {
if (m_primitiveType == PrimitiveType::Quads) {
for (unsigned int n = 0; n < 4; n++) {
math::Vec3f v1 (m_vertices[i*4+n].position.x, m_vertices[i*4+n].position.y, m_vertices[i*4+n].position.z);
math::Vec3f v2;
math::Vec3f v3;
if (n == 0) {
v2 = math::Vec3f (m_vertices[i*4+3].position.x, m_vertices[i*4+3].position.y, m_vertices[i*4+3].position.z);
} else {
v2 = math::Vec3f (m_vertices[i*4+n-1].position.x, m_vertices[i*4+n-1].position.y, m_vertices[i*4+n-1].position.z);
}
if (n == 3) {
v3 = math::Vec3f (m_vertices[i*4].position.x, m_vertices[i*4].position.y, m_vertices[i*4].position.z);
} else {
v3 = math::Vec3f (m_vertices[i*4+n+1].position.x, m_vertices[i*4+n+1].position.y, m_vertices[i*4+n+1].position.z);
}
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i*4+n] = Vector3f(normal.x, normal.y, normal.z);
}
} else if (m_primitiveType == PrimitiveType::Triangles) {
for (unsigned int n = 0; n < 3; n++) {
math::Vec3f v1 (m_vertices[i*3+n].position.x, m_vertices[i*3+n].position.y, m_vertices[i*3+n].position.z);
math::Vec3f v2;
math::Vec3f v3;
if (n == 0) {
v2 = math::Vec3f (m_vertices[i*3+2].position.x, m_vertices[i*3+2].position.y, m_vertices[i*3+2].position.z);
} else {
v2 = math::Vec3f (m_vertices[i*3+n-1].position.x, m_vertices[i*3+n-1].position.y, m_vertices[i*3+n-1].position.z);
}
if (n == 2) {
v3 = math::Vec3f (m_vertices[i*3].position.x, m_vertices[i*3].position.y, m_vertices[i*3].position.z);
} else {
v3 = math::Vec3f (m_vertices[i*3+n+1].position.x, m_vertices[i*3+n+1].position.y, m_vertices[i*3+n+1].position.z);
}
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i*3+n] = Vector3f(normal.x, normal.y, normal.z);
}
} else if (m_primitiveType == PrimitiveType::TriangleStrip) {
if (i == 0) {
for (unsigned int n = 0; n < 3; n++) {
math::Vec3f v1 (m_vertices[n].position.x, m_vertices[n].position.y, m_vertices[n].position.z);
math::Vec3f v2;
math::Vec3f v3;
if (n == 0) {
v2 = math::Vec3f (m_vertices[2].position.x, m_vertices[2].position.y, m_vertices[2].position.z);
} else {
v2 = math::Vec3f (m_vertices[n-1].position.x, m_vertices[n-1].position.y, m_vertices[n-1].position.z);
}
if (n == 2) {
v3 = math::Vec3f (m_vertices[0].position.x, m_vertices[0].position.y, m_vertices[0].position.z);
} else {
v3 = math::Vec3f (m_vertices[n+1].position.x, m_vertices[n+1].position.y, m_vertices[n+1].position.z);
}
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i*3+n] = Vector3f(normal.x, normal.y, normal.z);
}
} else {
math::Vec3f v1 (m_vertices[i+2].position.x, m_vertices[i+2].position.y, m_vertices[i+2].position.z);
math::Vec3f v2 (m_vertices[i+1].position.x, m_vertices[i+1].position.y, m_vertices[i+1].position.z);
math::Vec3f v3 (m_vertices[i].position.x, m_vertices[i].position.y, m_vertices[i].position.z);
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i+3] = Vector3f(normal.x, normal.y, normal.z);
}
} else if (m_primitiveType == TriangleFan) {
if (i == 0) {
for (unsigned int n = 0; n < 3; n++) {
math::Vec3f v1 (m_vertices[n].position.x, m_vertices[n].position.y, m_vertices[n].position.z);
math::Vec3f v2;
math::Vec3f v3;
if (n == 0) {
v2 = math::Vec3f (m_vertices[2].position.x, m_vertices[2].position.y, m_vertices[2].position.z);
} else {
v2 = math::Vec3f (m_vertices[n-1].position.x, m_vertices[n-1].position.y, m_vertices[n-1].position.z);
}
if (n == 2) {
v3 = math::Vec3f (m_vertices[0].position.x, m_vertices[0].position.y, m_vertices[0].position.z);
} else {
v3 = math::Vec3f (m_vertices[n+1].position.x, m_vertices[n+1].position.y, m_vertices[n+1].position.z);
}
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i*3+n] = Vector3f(normal.x, normal.y, normal.z);
}
} else {
math::Vec3f v1 (m_vertices[i+2].position.x, m_vertices[i+2].position.y, m_vertices[i+2].position.z);
math::Vec3f v2 (m_vertices[i+1].position.x, m_vertices[i+1].position.y, m_vertices[i+1].position.z);
math::Vec3f v3 (m_vertices[0].position.x, m_vertices[0].position.y, m_vertices[0].position.z);
math::Vec3f dir1 = v2 - v1;
math::Vec3f dir2 = v3 - v1;
math::Vec3f normal = dir1.cross(dir2).normalize();
m_normals[i+3] = Vector3f(normal.x, normal.y, normal.z);
}
}
}
for (unsigned int i = 0; i < m_normals.size(); i++) {
m_vertices[i].normal = m_normals[i];
}
}
needToUpdateNormals = false;*/
}
bool VertexBuffer::isLoop() {
return loop;
}
void VertexBuffer::transform(TransformMatrix tm) {
/*for (unsigned int i = 0; i < m_vertices.size(); i++) {
if (m_locals.size() < m_vertices.size())
m_locals.push_back(math::Vec3f(m_vertices[i].position.x, m_vertices[i].position.y,m_vertices[i].position.z));
math::Vec3f t = tm.transform(m_locals[i]);
m_vertices[i].position.x = t.x;
m_vertices[i].position.y = t.y;
m_vertices[i].position.z = t.z;
}
needToUpdateVertexBuffer = true;*/
}
////////////////////////////////////////////////////////////
VertexBuffer::VertexBuffer(PrimitiveType type, unsigned int vertexCount, Entity* entity) :
m_vertices (vertexCount),
m_primitiveType(type),
m_entity(entity)
{
vboVertexBuffer = 0;
vboNormalBuffer = 0;
vboIndexBuffer = 0;
oldVerticesSize = 0;
oldIndexesSize = 0;
oldMaterialTypeSize = 0;
oldLayerSize = 0;
oldSpecularSize = 0;
oldLightInfosSize = 0;
vboMaterialType = 0;
vboLayer = 0;
vboSpecular = 0;
vboLightInfos = 0;
needToUpdateVertexBuffer = true;
needToUpdateIndexBuffer = true;
needToUpdateMaterialTypeBuffer = true;
needToUpdateLayersBuffer = true;
needToUpdateSpecularBuffer = true;
needToUpdateLightInfos = true;
loop = true;
nbVerticesPerFace = 4;
}
void VertexBuffer::setEntity(Entity* entity) {
m_entity = entity;
}
Entity* VertexBuffer::getEntity() {
return m_entity;
}
void VertexBuffer::addInstancedRenderingInfos(unsigned int numIndexes, unsigned int baseVertex, unsigned int baseIndex) {
m_numIndexes.push_back(numIndexes);
m_baseVertices.push_back(baseVertex);
m_baseIndexes.push_back(baseIndex);
}
void VertexBuffer::addIndex(unsigned int index) {
m_indexes.push_back(index);
////////std::cout<<"vb index : "<<index<<"size : "<<m_indexes.size()<<std::endl;
if (!needToUpdateIndexBuffer)
needToUpdateIndexBuffer = true;
}
void VertexBuffer::addLightInfos (math::Vec3f center, Color color) {
////////std::cout<<"add light info : "<<center<<(int) color.r<<","<<(int) color.g<<","<<(int) color.b<<","<<(int) color.a<<std::endl;
LightInfos li;
li.center = center;
li.color = color;
m_lightInfos.push_back(li);
if (!needToUpdateLightInfos)
needToUpdateLightInfos = true;
}
void VertexBuffer::update(VertexArray& va) {
for (unsigned int i = 0; i < va.getVertexCount(); i++) {
m_vertices[va.m_indexes[i]] = va[i];
}
if (!needToUpdateIndexBuffer)
needToUpdateVertexBuffer = true;
}
void VertexBuffer::remove(VertexArray& va) {
/*for (unsigned int i = 0; i < va.getVertexCount(); i++) {
unsigned int first = va.m_indexes[0];
std::vector<Vertex>::iterator itv;
std::vector<math::Vec3f>::iterator itn;
std::vector<unsigned int>::iterator iti;
for (iti = m_indexes.begin(); iti != m_indexes.end();) {
if (*iti == va.m_indexes[i]) {
for (itn = m_normals.begin(); itn != m_normals.end();) {
if (*iti == m_normals[i].y) {
itn = m_normals.erase(itn);
} else {
itn++;
}
}
for (itv = m_vertices.begin(); itv != m_vertices.end();) {
if (*iti == va.m_indexes[i]) {
itv = m_vertices.erase(itv);
} else {
itv++;
}
}
iti = m_indexes.erase(iti);
} else {
iti++;
}
}
for (unsigned int i = 0; i < m_indexes.size(); i++) {
if (m_indexes[i] > first) {
m_indexes[i] -= va.getVertexCount();
}
}
if(!needToUpdateVertexBuffer)
needToUpdateVertexBuffer = true;
if(!needToUpdateIndexBuffer)
needToUpdateIndexBuffer = true;
}*/
}
std::vector<unsigned int> VertexBuffer::getBaseIndexes() {
return m_baseIndexes;
}
std::vector<unsigned int> VertexBuffer::getIndexes() {
return m_indexes;
}
///////////////////////////////////////////////////////////
unsigned int VertexBuffer::getVertexCount() const
{
return static_cast<unsigned int>(m_vertices.size());
}
////////////////////////////////////////////////////////////
Vertex& VertexBuffer::operator [](unsigned int index)
{
return m_vertices[index];
}
////////////////////////////////////////////////////////////
const Vertex& VertexBuffer::operator [](unsigned int index) const
{
return m_vertices[index];
}
////////////////////////////////////////////////////////////
void VertexBuffer::clear()
{
m_vertices.clear();
m_indexes.clear();
m_normals.clear();
m_locals.clear();
m_texturesIndexes.clear();
m_MaterialType.clear();
m_layers.clear();
m_specular.clear();
m_lightInfos.clear();
}
void VertexBuffer::resetIndexes(std::vector<unsigned int> indexes) {
m_indexes = indexes;
needToUpdateIndexBuffer = true;
}
////////////////////////////////////////////////////////////
void VertexBuffer::resize(unsigned int vertexCount)
{
m_vertices.resize(vertexCount);
}
////////////////////////////////////////////////////////////
void VertexBuffer::append(const Vertex& vertex, unsigned int textureIndex)
{
/*bool contains = false;
for (unsigned int i = 0; i < m_vertices.size(); i++) {
if (m_vertices[i] == vertex)
contains = true;
}*/
//if (!contains) {
////////std::cout<<"position : "<<vertex.position.x<<" "<<vertex.position.y<<" "<<vertex.position.z<<std::endl;
m_vertices.push_back(vertex);
m_texturesIndexes.push_back(textureIndex);
/*m_vPosX.push_back(vertex.position.x);
m_vPosY.push_back(vertex.position.y);
m_vPosZ.push_back(vertex.position.z);
m_vPosW.push_back(1);
m_vcRed.push_back(vertex.color.r);
m_vcBlue.push_back(vertex.color.g);
m_vcGreen.push_back(vertex.color.b);
m_vcAlpha.push_back(vertex.color.a);
m_ctX.push_back(vertex.texCoords.x);
m_ctY.push_back(vertex.texCoords.y);
m_locals.push_back(math::Vec3f(vertex.position.x, vertex.position.y, vertex.position.z));*/
if (!needToUpdateVertexBuffer)
needToUpdateVertexBuffer = true;
needToUpdateNormals = true;
}
void VertexBuffer::addMaterialType(unsigned int materialType) {
m_MaterialType.push_back(materialType);
needToUpdateMaterialTypeBuffer = true;
}
void VertexBuffer::addLayer(unsigned int layer) {
m_layers.push_back(layer);
needToUpdateLayersBuffer = true;
}
void VertexBuffer::addSpecular(float specularIntensity, float specularPower) {
m_specular.push_back(math::Vec2f(specularIntensity, specularPower));
needToUpdateSpecularBuffer = true;
}
math::Vec3f VertexBuffer::getLocal(unsigned int index) const {
return m_locals[index];
}
void VertexBuffer::setLocal(unsigned int index, math::Vec3f v) {
m_locals[index] = v;
}
////////////////////////////////////////////////////////////
void VertexBuffer::setPrimitiveType(PrimitiveType type)
{
m_primitiveType = type;
}
////////////////////////////////////////////////////////////
PrimitiveType VertexBuffer::getPrimitiveType() const
{
return m_primitiveType;
}
bool VertexBuffer::operator== (const VertexBuffer &other) {
if (getVertexCount() != other.getVertexCount())
return false;
if (m_primitiveType != other.m_primitiveType)
return false;
for (unsigned int i = 0; i < getVertexCount(); i++)
if (!(m_vertices[i] == other.m_vertices[i]))
return false;
return true;
}
void VertexBuffer::addTransformId(unsigned int id, unsigned int vertexId) {
m_normals.push_back(math::Vec3f(id, vertexId, 0));
}
void VertexBuffer::resizeVertices(unsigned int newSize) {
m_vertices.resize(newSize);
m_texturesIndexes.resize(newSize);
needToUpdateVertexBuffer = true;
needToUpdateNormals = true;
}
void VertexBuffer::resizeMaterialTypes(unsigned int newSize) {
m_MaterialType.resize(newSize);
needToUpdateMaterialTypeBuffer = true;
}
void VertexBuffer::resizeLayers(unsigned int newSize) {
m_layers.resize(newSize);
needToUpdateLayersBuffer = true;
}
void VertexBuffer::resizeSpeculars(unsigned int newSize) {
m_specular.resize(newSize);
needToUpdateSpecularBuffer = true;
}
void VertexBuffer::resizeLightInfos(unsigned int newSize) {
m_lightInfos.resize(newSize);
needToUpdateLightInfos = true;
}
std::vector<Vertex>& VertexBuffer::getVertices() {
return m_vertices;
}
std::vector<unsigned int>& VertexBuffer::getTextureIndexes() {
return m_texturesIndexes;
}
std::vector<unsigned int>& VertexBuffer::getLayers() {
return m_layers;
}
std::vector<unsigned int>& VertexBuffer::getMaterialTypes () {
return m_MaterialType;
}
std::vector<math::Vec2f>& VertexBuffer::getSpeculars() {
return m_specular;
}
std::vector<VertexBuffer::LightInfos>& VertexBuffer::getLightInfos() {
return m_lightInfos;
}
void VertexBuffer::update() {
if (!m_vertices.empty()) {
std::vector<GlVertex> glVerts(m_vertices.size());
for (unsigned int i = 0; i < m_vertices.size(); i++) {
//////std::cout<<"position : "<<m_vertices[i].position<<std::endl;
glVerts[i].position.x = m_vertices[i].position[0];
glVerts[i].position.y = m_vertices[i].position[1];
glVerts[i].position.z = m_vertices[i].position[2];
glVerts[i].color.r = m_vertices[i].color.r;
glVerts[i].color.g = m_vertices[i].color.g;
glVerts[i].color.b = m_vertices[i].color.b;
glVerts[i].color.a = m_vertices[i].color.a;
glVerts[i].texCoords.x = m_vertices[i].texCoords[0];
glVerts[i].texCoords.y = m_vertices[i].texCoords[1];
glVerts[i].normal.x = m_vertices[i].normal[0];
glVerts[i].normal.y = m_vertices[i].normal[1];
glVerts[i].normal.z = m_vertices[i].normal[2];
}
//computeNormals();
if (GLEW_ARB_vertex_buffer_object) {
if (needToUpdateVertexBuffer) {
if (vboVertexBuffer == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboVertexBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), &m_vertices[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer));
pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_vertices[0], m_vertices.size() * sizeof(Vertex));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
/*if (vboNormalBuffer == 0) {
////////std::cout<<"create vbo normal buffer"<<std::endl;
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboNormalBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboNormalBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_normals.size() * sizeof(math::Vec3f), &m_normals[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboNormalBuffer));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_normals[0], m_normals.size() * sizeof(math::Vec3f));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
if (vboTextureIndexesBuffer == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboTextureIndexesBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboTextureIndexesBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_texturesIndexes.size() * sizeof(unsigned int), &m_texturesIndexes[0], GL_DYNAMIC_DRAW));
////////std::cout<<"vbo index texture : "<<vboTextureIndexesBuffer<<std::endl;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboTextureIndexesBuffer));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo, &m_texturesIndexes[0], m_texturesIndexes.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
needToUpdateVertexBuffer = false;
}*/
if (needToUpdateIndexBuffer) {
if (vboIndexBuffer == 0) {
////////std::cout<<"create index vbo buffer"<<std::endl;
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboIndexBuffer = static_cast<unsigned int>(vbo);
}
if (oldIndexesSize != m_indexes.size()) {
////////std::cout<<"size changed : update index vbo buffer"<<std::endl;
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndexBuffer));
glCheck(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexes.size() * sizeof(unsigned int), &m_indexes[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update index vbo buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboVertexBuffer));
glCheck(pos_vbo = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_indexes[0], m_indexes.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
needToUpdateIndexBuffer = false;
}
/*if (needToUpdateMaterialTypeBuffer) {
if (vboMaterialType == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboMaterialType = static_cast<unsigned int>(vbo);
}
if (oldMaterialTypeSize != m_MaterialType.size()) {
////////std::cout<<"size changed : update index vbo buffer"<<std::endl;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboMaterialType));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_MaterialType.size() * sizeof(unsigned int), &m_MaterialType[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update index vbo buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboMaterialType));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_MaterialType[0], m_MaterialType.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
needToUpdateMaterialTypeBuffer = false;
}
if (needToUpdateLayersBuffer) {
if (vboLayer == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboLayer = static_cast<unsigned int>(vbo);
}
if (oldLayerSize != m_layers.size()) {
////////std::cout<<"size changed : update index vbo buffer"<<std::endl;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboLayer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_layers.size() * sizeof(unsigned int), &m_layers[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update index vbo buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboLayer));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_layers[0], m_layers.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
needToUpdateLayersBuffer = false;
}
if (needToUpdateSpecularBuffer) {
if (vboSpecular == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboSpecular = static_cast<unsigned int>(vbo);
}
if (oldSpecularSize != m_specular.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboSpecular));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_specular.size() * sizeof(math::Vec2f), &m_specular[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update index vbo buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboSpecular));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_specular[0], m_specular.size() * sizeof(math::Vec2f));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
}
if (needToUpdateLightInfos) {
if (vboLightInfos == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboLightInfos = static_cast<unsigned int>(vbo);
}
if (oldLightInfosSize != m_lightInfos.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboLightInfos));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_lightInfos.size() * sizeof(LightInfos), &m_lightInfos[0], GL_DYNAMIC_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"size : "<<m_lightInfos.size()<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboLightInfos));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_lightInfos[0], m_lightInfos.size() * sizeof(LightInfos));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}*/
}
oldVerticesSize = m_vertices.size();
oldIndexesSize = m_indexes.size();
oldMaterialTypeSize = m_MaterialType.size();
oldLayerSize = m_layers.size();
oldSpecularSize = m_specular.size();
oldLightInfosSize = m_lightInfos.size();
}
}
}
////////////////////////////////////////////////////////////
void VertexBuffer::draw(RenderTarget& target, RenderStates states)
{
if (!m_vertices.empty()) {
if (GLEW_ARB_vertex_buffer_object) {
if (needToUpdateVertexBuffer) {
if (vboVertexBuffer == 0) {
////////std::cout<<"create vbo vertex buffer"<<std::endl;
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboVertexBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
////////std::cout<<"size changed : update vbo vertex buffer"<<std::endl;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), &m_vertices[0], GL_STREAM_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update vbo vertex buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboVertexBuffer));
pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_vertices[0], m_vertices.size() * sizeof(Vertex));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
if (vboNormalBuffer == 0) {
////////std::cout<<"create vbo normal buffer"<<std::endl;
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboNormalBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
////////std::cout<<"size changed : update vbo normal buffer"<<std::endl;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboNormalBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_normals.size() * sizeof(math::Vec3f), &m_normals[0], GL_STREAM_DRAW));
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update vbo normal buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboNormalBuffer));
pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_normals[0], m_normals.size() * sizeof(math::Vec3f));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
if (vboTextureIndexesBuffer == 0) {
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboTextureIndexesBuffer = static_cast<unsigned int>(vbo);
}
if (oldVerticesSize != m_vertices.size()) {
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboTextureIndexesBuffer));
glCheck(glBufferData(GL_ARRAY_BUFFER, m_texturesIndexes.size() * sizeof(unsigned int), &m_texturesIndexes[0], GL_DYNAMIC_DRAW));
/*for (unsigned int i = 0; i < m_texturesIndexes.size(); i++) {
//////std::cout<<"texture indexes size : "<<m_texturesIndexes.size()<<" index : "<<m_texturesIndexes[i]<<std::endl;
}*/
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
} else {
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ARRAY_BUFFER, vboTextureIndexesBuffer));
glCheck(pos_vbo = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo, &m_texturesIndexes[0], m_texturesIndexes.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ARRAY_BUFFER, 0));
}
needToUpdateVertexBuffer = false;
}
if (needToUpdateIndexBuffer) {
if (vboIndexBuffer == 0) {
////////std::cout<<"create index vbo buffer"<<std::endl;
GLuint vbo;
glCheck(glGenBuffers(1, &vbo));
vboIndexBuffer = static_cast<unsigned int>(vbo);
}
if (oldIndexesSize != m_indexes.size()) {
////////std::cout<<"size changed : update index vbo buffer"<<std::endl;
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndexBuffer));
glCheck(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexes.size() * sizeof(unsigned int), &m_indexes[0], GL_STREAM_DRAW));
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
} else {
////////std::cout<<"update index vbo buffer"<<std::endl;
GLvoid *pos_vbo = nullptr;
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboVertexBuffer));
glCheck(pos_vbo = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY));
if (pos_vbo != nullptr) {
memcpy(pos_vbo,&m_indexes[0], m_indexes.size() * sizeof(unsigned int));
glCheck(glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER));
pos_vbo = nullptr;
}
glCheck(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
needToUpdateIndexBuffer = false;
}
target.drawVertexBuffer(*this, states);
}
oldVerticesSize = m_vertices.size();
oldIndexesSize = m_indexes.size();
}
}
////////////////////////////////////////////////////////////
physic::BoundingBox VertexBuffer::getBounds()
{
if (!m_vertices.empty())
{
float left = m_vertices[0].position.x();
float top = m_vertices[0].position.y();
float right = m_vertices[0].position.x();
float bottom = m_vertices[0].position.y();
float nearest = m_vertices[0].position.z();
float farest = m_vertices[0].position.z();
for (std::size_t i = 1; i < m_vertices.size(); ++i)
{
math::Vec3f position = m_vertices[i].position;
// Update left and right
if (position.x() < left)
left = position.x();
else if (position.x() > right)
right = position.x();
// Update top and bottom
if (position.y() < top)
top = position.y();
else if (position.y() > bottom)
bottom = position.y();
//Update the near and the far.
if (position.z() < farest)
farest = position.z();
else if (position.z() > nearest)
nearest = position.z();
}
return physic::BoundingBox(left, top, nearest, right - left, bottom - top, farest - nearest);
}
else
{
// Array is empty
return physic::BoundingBox();
}
}
void VertexBuffer::updateVBOBuffer() {
needToUpdateVertexBuffer = true;
}
void VertexBuffer::remove (unsigned int index) {
std::vector<Vertex>::iterator it = m_vertices.begin();
for (unsigned int i = 0; i < m_vertices.size(); i++) {
if (i == index) {
it = m_vertices.erase(it);
} else {
it++;
}
std::vector<unsigned int>::iterator it2 = m_indexes.begin();
for (unsigned int j = 0; j < m_indexes.size(); j++) {
if (i == m_indexes[j]) {
it2 = m_indexes.erase(it2);
} else {
it2++;
}
}
}
}
VertexBuffer::~VertexBuffer() {
GLuint vbo = static_cast<GLuint>(vboVertexBuffer);
glCheck(glDeleteBuffers(1, &vbo));
vbo = static_cast<GLuint>(vboNormalBuffer);
glCheck(glDeleteBuffers(1, &vbo));
vbo = static_cast<GLuint>(vboIndexBuffer);
glCheck(glDeleteBuffers(1, &vbo));
}
#endif // VULKAN
}
} // namespace sf3
And my binding descriptions :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
alignas(16) math::Vec3f position; ///< 3D position of the vertex
alignas(16) math::Vec2f texCoords; ///< Coordinates of the texture's pixel to map to the vertex
alignas(16) math::Vec3f normal;
//bone indexes which will influence this vertex
int m_BoneIDs[MAX_BONE_INFLUENCE];
//weights from each bone
float m_Weights[MAX_BONE_INFLUENCE];
Color color; ///< Color of the vertex
int entityId;
int particleId;
int drawableDataID;
#ifdef VULKAN
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription bindingDescription{};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
return bindingDescription;
}
static std::array<VkVertexInputAttributeDescription, 5> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 5> attributeDescriptions{};
attributeDescriptions[0].binding = 0;
attributeDescriptions[0].location = 0;
attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[0].offset = offsetof(Vertex, position);
attributeDescriptions[1].binding = 0;
attributeDescriptions[1].location = 1;
attributeDescriptions[1].format = VK_FORMAT_R8G8B8A8_UNORM;
attributeDescriptions[1].offset = offsetof(Vertex, color);
attributeDescriptions[2].binding = 0;
attributeDescriptions[2].location = 2;
attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[2].offset = offsetof(Vertex, texCoords);
attributeDescriptions[3].binding = 0;
attributeDescriptions[3].location = 3;
attributeDescriptions[3].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[3].offset = offsetof(Vertex, normal);
attributeDescriptions[4].binding = 0;
attributeDescriptions[4].location = 4;
attributeDescriptions[4].format = VK_FORMAT_R32_SINT;
attributeDescriptions[4].offset = offsetof(Vertex, drawableDataID);
return attributeDescriptions;
}
#endif
};
}
}
And I update my staging buffers like this :
if (vbBindlessTex[p].getVertexCount() > 0) {
////std::cout<<"size vb : "<<vbBindlessTex[p].getVertexCount()<<std::endl;
vbBindlessTex[p].updateStagingBuffers(currentFrame);
}
if (vbBindlessTexIndexed[p].getVertexCount() > 0) {
//std::cout<<"size vb indexed : "<<vbBindlessTexIndexed[p].getIndicesSize()<<std::endl;
vbBindlessTexIndexed[p].updateStagingBuffers(currentFrame);
}
I can’t figure out why, since I added new SSBOs, I’ve always the same values for the vertex attributes in only one of my vertex shader. Or everything worked fine before. I searched for 2 days but, can’t debug this. And the most suprising things : it works when I draw my reflect entities with instance count > 1 but when I draw them with instancedcount = 1 I’ve always the same vertices attributes in the reflect refract vertex shader.
Is it a driver issue ?
Thanks.