137 lines
4.3 KiB
C++
137 lines
4.3 KiB
C++
#include "graphics/instancedraw.h"
|
|
#include "graphics/texture.h"
|
|
|
|
TileTextureInstance::TileTextureInstance(const char* texturePath)
|
|
{
|
|
texture = new Texture();
|
|
texture->loadTexture(texturePath);
|
|
if (texture)
|
|
setup();
|
|
}
|
|
|
|
TileTextureInstance::TileTextureInstance(const std::vector<const char*> texturePaths)
|
|
{
|
|
textures = new TextureArray();
|
|
if (textures->loadTextures(texturePaths))
|
|
setup();
|
|
}
|
|
|
|
void TileTextureInstance::setup()
|
|
{
|
|
glGenVertexArrays(1, &VAO);
|
|
glGenBuffers(1, &VBO);
|
|
glGenBuffers(1, &EBO);
|
|
|
|
glBindVertexArray(VAO);
|
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
|
glEnableVertexAttribArray(0);
|
|
glEnableVertexAttribArray(1);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
glGenBuffers(1, &instanceVBO);
|
|
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(InstanceData) * MAX_INSTANCES, nullptr, GL_DYNAMIC_DRAW);
|
|
|
|
// tileIndex instanceData layout position 2
|
|
glVertexAttribIPointer(2, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, tileIndex)));
|
|
glEnableVertexAttribArray(2);
|
|
glVertexAttribDivisor(2, 1);
|
|
|
|
// textureIndex instanceData layout position 3 -> We are using multiple textures to hold each tileset
|
|
glVertexAttribIPointer(3, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, textureIndex)));
|
|
glEnableVertexAttribArray(3);
|
|
glVertexAttribDivisor(3, 1);
|
|
|
|
// tilesPerRow instanceData layout position 4, This is needed since we are supporting multiple tilesets
|
|
// of different sizes
|
|
glVertexAttribIPointer(4, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, tilesPerRow)));
|
|
glEnableVertexAttribArray(4);
|
|
glVertexAttribDivisor(4, 1);
|
|
|
|
// startID instanceData layout position 5
|
|
glVertexAttribIPointer(5, 1, GL_INT, sizeof(InstanceData), (void*)(offsetof(InstanceData, startID)));
|
|
glEnableVertexAttribArray(5);
|
|
glVertexAttribDivisor(5, 1);
|
|
|
|
// originalSize instanceData layout position 6
|
|
glVertexAttribPointer(6, 2, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (void*)(offsetof(InstanceData, originalSize)));
|
|
glEnableVertexAttribArray(6);
|
|
glVertexAttribDivisor(6, 1);
|
|
|
|
// modelMatrix instanceData as 4 vec 4s (a 4x4 matrix) layout head position 7
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
glVertexAttribPointer(7 + i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), (void*)(offsetof(InstanceData, modelMatrix) + (sizeof(glm::vec4) * i)));
|
|
glEnableVertexAttribArray(7 + i);
|
|
glVertexAttribDivisor(7 + i, 1);
|
|
}
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
void TileTextureInstance::updateInstanceData(const std::vector<InstanceData>& instanceData)
|
|
{
|
|
if (instanceData.empty())
|
|
return;
|
|
numOfInstances = instanceData.size();
|
|
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
|
|
|
|
InstanceData* instances = (InstanceData*)glMapBufferRange(GL_ARRAY_BUFFER, 0,
|
|
sizeof(InstanceData) * instanceData.size(),
|
|
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
|
if (!instances)
|
|
return;
|
|
|
|
if (instances)
|
|
{
|
|
std::memcpy(instances, instanceData.data(), sizeof(InstanceData) * instanceData.size());
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
}
|
|
|
|
/*
|
|
for (int i = 0; i < instanceData.size(); i++)
|
|
{
|
|
instances[i].modelMatrix = instanceData[i].modelMatrix;
|
|
instances[i].originalSize = instanceData[i].originalSize;
|
|
instances[i].tileIndex = instanceData[i].tileIndex;
|
|
instances[i].textureIndex = instanceData[i].textureIndex;
|
|
instances[i].tilesPerRow = instanceData[i].tilesPerRow;
|
|
instances[i].startID = instanceData[i].startID;
|
|
}
|
|
*/
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void TileTextureInstance::draw()
|
|
{
|
|
// bind textures
|
|
if (texture)
|
|
texture->bind();
|
|
else if (textures)
|
|
textures->bind();
|
|
|
|
glBindVertexArray(VAO);
|
|
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, numOfInstances);
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
TileTextureInstance::~TileTextureInstance()
|
|
{
|
|
if (texture)
|
|
delete texture;
|
|
else if (textures)
|
|
delete textures;
|
|
glDeleteBuffers(1, &VBO);
|
|
glDeleteBuffers(1, &EBO);
|
|
glDeleteVertexArrays(1, &VAO);
|
|
}
|