#pragma once #include "stdafx.h" #include #include #include "Exception.h" namespace { struct EmptyElement {}; } template > class Batch { public: typedef GLsizei SizeType; Batch( const Renderable* renderable, const SizeType& element_render_count ) : m_p_renderable(renderable), m_element_render_count(element_render_count), m_element_buffers(element_buffer_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); glGenBuffers(element_buffer_count, m_element_buffers.data()); } virtual ~Batch() { glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_vertex_vbo); glDeleteBuffers(1, &m_index_vbo); glDeleteBuffers(element_buffer_count, m_element_buffers.data()); } 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_buffers(); glBindVertexArray(m_vao); // Possibly want to move these three lines into the init function glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo); setup_vao(); glBindVertexArray(NULL); } void prerender() { update_element_buffers(); } 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, m_element_render_count ); glBindVertexArray(NULL); } void set_element_render_count(const SizeType& element_render_count) { m_element_render_count = element_render_count; } const Renderable* get_renderable() const { return m_p_renderable; } SizeType get_element_render_count() const { return m_element_render_count; } protected: virtual void setup_element_buffers() {} virtual void setup_vao() = 0; virtual void update_element_buffers() {} const Renderable* m_p_renderable; SizeType m_element_render_count; GLuint m_vertex_vbo; std::vector m_element_buffers; private: GLuint m_vao; GLuint m_index_vbo; GLenum m_gl_index_type; };