charcoal/OpenGLEngine/Batch.h

117 lines
2.8 KiB
C
Raw Normal View History

#pragma once
#include "stdafx.h"
#include <cstddef>
#include <vector>
#include "Exception.h"
namespace
{
struct EmptyElement {};
}
template <typename VertexType, typename IndexType, typename ElementType = EmptyElement, typename RenderableType = Renderable<VertexType, IndexType> >
class Batch
{
public:
typedef GLsizei SizeType;
Batch(
const RenderableType* renderable,
const SizeType& element_count,
const SizeType& element_render_count
)
: m_p_renderable(renderable), m_elements(element_count), m_element_render_count(element_render_count)
{
if (std::is_same<unsigned int, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_INT;
}
else if (std::is_same<unsigned short, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_SHORT;
}
else if (std::is_same<unsigned char, IndexType>::value)
{
m_gl_index_type = GL_UNSIGNED_BYTE;
}
else
{
throw EXCEPTION("Invalid Batch IndexType");
}
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vertex_vbo);
glGenBuffers(1, &m_index_vbo);
}
virtual ~Batch()
{
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vertex_vbo);
glDeleteBuffers(1, &m_index_vbo);
}
void init()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glBufferData(GL_ARRAY_BUFFER, m_p_renderable->get_mesh()->vertex_count * sizeof(VertexType), m_p_renderable->get_mesh()->vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_p_renderable->get_mesh()->index_count * sizeof(IndexType), m_p_renderable->get_mesh()->indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);
setup_element_buffer();
glBindVertexArray(m_vao); // Possibly want to move these three lines into the init function
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
setup_vao();
glBindVertexArray(NULL);
}
void render() const
{
glBindVertexArray(m_vao);
glDrawElementsInstanced(
m_p_renderable->get_draw_mode(),
m_p_renderable->get_mesh()->index_count,
m_gl_index_type,
0,
(GLsizei)m_element_render_count
);
glBindVertexArray(NULL);
}
void set_element_render_count(const SizeType& element_render_count)
{
m_element_render_count = element_render_count;
}
ElementType& get_element() { return m_elements[0]; }
ElementType& get_element(const SizeType& index) { return m_elements[index]; }
const ElementType& get_element() const { return m_elements[0]; }
const ElementType& get_element(const SizeType& index) const { return m_elements[index]; }
protected:
virtual void setup_element_buffer() {}
virtual void setup_vao() = 0;
const RenderableType* m_p_renderable;
std::vector<ElementType> m_elements;
SizeType m_element_render_count;
private:
GLuint m_vao;
GLuint m_vertex_vbo;
GLuint m_index_vbo;
GLenum m_gl_index_type;
};