charcoal/OpenGLEngine/Batch.h
elipzer 991b52b233 Almost Finished Builtin
Builtin general structure created. Added a builtin::BasicScene
class for quick general testing of the engine on different systems.
The builtin::BasicScene class greatly reduces the amount of code
needed to be handled by the developer by offering a pre-made way
to handle it. It even includes pre-made shaders!
2018-09-13 00:51:47 -04:00

121 lines
2.9 KiB
C++

#pragma once
#include "stdafx.h"
#include <cstddef>
#include <vector>
#include "Exception.h"
namespace charcoal
{
template <typename VertexType, typename IndexType, int element_buffer_count, typename Renderable = Renderable<VertexType, IndexType> >
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<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);
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<GLuint> m_element_buffers;
private:
GLuint m_vao;
GLuint m_index_vbo;
GLenum m_gl_index_type;
};
}