#pragma once #include "stdafx.h" #include #include #include "Exception.h" namespace { struct EmptyElement {}; } template > 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::value) { m_gl_index_type = GL_UNSIGNED_INT; } else if (std::is_same::value) { m_gl_index_type = GL_UNSIGNED_SHORT; } else if (std::is_same::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 m_elements; SizeType m_element_render_count; private: GLuint m_vao; GLuint m_vertex_vbo; GLuint m_index_vbo; GLenum m_gl_index_type; };