charcoal/charcoal-builtin/PoseableBatch.h
2022-08-01 19:07:37 -05:00

88 lines
3.9 KiB
C++

#pragma once
#include <charcoal/Batch.h>
#include <charcoal/Renderable.h>
#include <charcoal/Poseable.h>
#include "BuiltinBatch.h"
namespace charcoal
{
namespace builtin
{
// Note: If anything is changed in this file, it must also be changed in Poseable2DBatch
template <typename VertexType, typename IndexType, int orientation_attrib_offset, typename RenderableType = RenderableT<VertexType, IndexType> >
class PoseableBatch : public builtin::Batch<VertexType, IndexType, 1, RenderableType>
{
public:
PoseableBatch(RenderableType* renderable)
: builtin::Batch<VertexType, IndexType, 1, RenderableType>(renderable, 0)
{}
virtual ~PoseableBatch() {}
void reset_rendered()
{
m_orientation_elements.clear();
charcoal::InstancedBatch<VertexType, IndexType, RenderableType>::set_render_count(0);
// Just thinking, maybe want to not make want set_render_count to be public... The end-developer
// could screw up things by using that function. Then again, it could allow for preventing of
// needing to resize the element buffers once that optimization is made.
}
void add_rendered(const Poseable& poseable)
{
m_orientation_elements.emplace_back(poseable.get_orientation_matrix());
charcoal::InstancedBatch<VertexType, IndexType, RenderableType>::m_render_count++;
}
protected:
void setup_element_buffers() override
{
// This is (was) worthless because it is also done in update_element_buffers.
//glBindBuffer(GL_ARRAY_BUFFER, charcoal::ElementBatch<1>::m_element_buffers[0]);
//glBufferData(GL_ARRAY_BUFFER, m_orientation_elements.size() * sizeof(mat4), NULL, GL_STREAM_DRAW);
// TODO: Find a way to not have to do a re-allocation every frame.
// While we're like this, I guess the adding and resetting of rendered can be changed though!
}
void resize_element_buffers() override
{
// Do nothing. This is done in update_element_buffers for some reason... Maybe this should be changed...
}
void update_element_buffers() override
{
// TODO: There are probably better ways to do this. Should check with the old engine to see what I did there.
glBindBuffer(GL_ARRAY_BUFFER, charcoal::ElementBatch<1>::m_element_buffers[0]);
glBufferData(GL_ARRAY_BUFFER, m_orientation_elements.size() * sizeof(mat4), NULL, GL_STREAM_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_orientation_elements.size() * sizeof(mat4), m_orientation_elements.data());
}
virtual void setup_vao_vertex() = 0;
void setup_vao() override
{
setup_vao_vertex();
glBindBuffer(GL_ARRAY_BUFFER, charcoal::ElementBatch<1>::m_element_buffers[0]);
glEnableVertexAttribArray(orientation_attrib_offset + 0);
glEnableVertexAttribArray(orientation_attrib_offset + 1);
glEnableVertexAttribArray(orientation_attrib_offset + 2);
glEnableVertexAttribArray(orientation_attrib_offset + 3);
glVertexAttribPointer(orientation_attrib_offset + 0, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(0 * sizeof(mat4::col_type)));
glVertexAttribPointer(orientation_attrib_offset + 1, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(1 * sizeof(mat4::col_type)));
glVertexAttribPointer(orientation_attrib_offset + 2, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(2 * sizeof(mat4::col_type)));
glVertexAttribPointer(orientation_attrib_offset + 3, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (void*)(3 * sizeof(mat4::col_type)));
glVertexAttribDivisor(orientation_attrib_offset + 0, 1); // Send the orientation data for each instance drawn
glVertexAttribDivisor(orientation_attrib_offset + 1, 1); // Send the orientation data for each instance drawn
glVertexAttribDivisor(orientation_attrib_offset + 2, 1); // Send the orientation data for each instance drawn
glVertexAttribDivisor(orientation_attrib_offset + 3, 1); // Send the orientation data for each instance drawn
}
std::vector<mat4> m_orientation_elements;
};
}
}