diff --git a/OpenGLEngine/Batch.h b/OpenGLEngine/Batch.h index ef2e72d..273ab37 100644 --- a/OpenGLEngine/Batch.h +++ b/OpenGLEngine/Batch.h @@ -12,7 +12,10 @@ namespace struct EmptyElement {}; } -template > +// TODO: Element buffer count as just the number of element types and allow multiple +// element types to be passed via Variadic Templates (see http://www.cplusplus.com/articles/EhvU7k9E/ ) +// This is effectively just support for more than one element vbo per rendered instance +template > class Batch { public: @@ -23,7 +26,7 @@ public: const SizeType& element_count, const SizeType& element_render_count ) - : m_p_renderable(renderable), m_elements(element_count), m_element_render_count(element_render_count) + : m_p_renderable(renderable), m_elements(element_count), m_element_render_count(element_render_count), m_element_buffers(element_buffer_count) { if (std::is_same::value) { @@ -45,6 +48,8 @@ public: glGenVertexArrays(1, &m_vao); glGenBuffers(1, &m_vertex_vbo); glGenBuffers(1, &m_index_vbo); + + glGenBuffers(element_buffer_count, m_element_buffers.data()); } virtual ~Batch() @@ -52,6 +57,8 @@ public: glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_vertex_vbo); glDeleteBuffers(1, &m_index_vbo); + + glDeleteBuffers(element_buffer_count, m_element_buffers.data()); } void init() @@ -63,10 +70,9 @@ public: 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(); + setup_element_buffers(); 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(); @@ -74,6 +80,11 @@ public: glBindVertexArray(NULL); } + void prerender() + { + update_element_buffers(); + } + void render() const { glBindVertexArray(m_vao); @@ -101,17 +112,21 @@ public: const ElementType& get_element(const SizeType& index) const { return m_elements[index]; } protected: - virtual void setup_element_buffer() {} + virtual void setup_element_buffers() {} virtual void setup_vao() = 0; + virtual void update_element_buffers() {} + const RenderableType* m_p_renderable; std::vector m_elements; SizeType m_element_render_count; + GLuint m_vertex_vbo; + std::vector m_element_buffers; + private: GLuint m_vao; - GLuint m_vertex_vbo; GLuint m_index_vbo; GLenum m_gl_index_type; }; \ No newline at end of file diff --git a/OpenGLEngine/MyBatch.cpp b/OpenGLEngine/MyBatch.cpp index 99f7037..b05d8e8 100644 --- a/OpenGLEngine/MyBatch.cpp +++ b/OpenGLEngine/MyBatch.cpp @@ -1,8 +1,30 @@ #include "MyBatch.h" +void MyBatch::setup_element_buffers() +{ + glBindBuffer(GL_ARRAY_BUFFER, m_element_buffers[0]); + // TODO: Maybe make the next line use a typedef instead of MyShaderProgram::ColorType + glBufferData(GL_ARRAY_BUFFER, m_elements.size() * sizeof(MyBatchTestShaderProgram::ColorType), NULL, GL_STREAM_DRAW); +} + void MyBatch::setup_vao() { + glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); + glBindBuffer(GL_ARRAY_BUFFER, m_element_buffers[0]); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL); + + glVertexAttribDivisor(0, 0); // Only need to send the mesh data once + glVertexAttribDivisor(1, 1); // Send the color data for each instance drawn +} + +void MyBatch::update_element_buffers() +{ + // 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, m_element_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, m_elements.size() * sizeof(MyBatchTestShaderProgram::ColorType), NULL, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, m_elements.size() * sizeof(MyBatchTestShaderProgram::ColorType), m_elements.data()); } diff --git a/OpenGLEngine/MyBatch.h b/OpenGLEngine/MyBatch.h index 7da452e..cdec6ed 100644 --- a/OpenGLEngine/MyBatch.h +++ b/OpenGLEngine/MyBatch.h @@ -2,16 +2,21 @@ #include "Batch.h" -#include "MyShaderProgram.h" +#include "MyBatchTestShaderProgram.h" -class MyBatch : public Batch +class MyBatch : public Batch { public: MyBatch( - const MyShaderProgram::RenderableType* renderable, + const MyBatchTestShaderProgram::RenderableType* renderable, const SizeType& element_count, const SizeType& element_render_count ) : Batch(renderable, element_count, element_render_count) {} + protected: + void setup_element_buffers() override; + void setup_vao() override; + + void update_element_buffers() override; }; \ No newline at end of file diff --git a/OpenGLEngine/MyBatchTestFragmentShader.glsl b/OpenGLEngine/MyBatchTestFragmentShader.glsl new file mode 100644 index 0000000..fd6f91c --- /dev/null +++ b/OpenGLEngine/MyBatchTestFragmentShader.glsl @@ -0,0 +1,7 @@ +#version 400 +in vec4 vert_color; +out vec4 frag_color; +void main() +{ + frag_color = vert_color; +} \ No newline at end of file diff --git a/OpenGLEngine/MyBatchTestShaderProgram.cpp b/OpenGLEngine/MyBatchTestShaderProgram.cpp new file mode 100644 index 0000000..fc57350 --- /dev/null +++ b/OpenGLEngine/MyBatchTestShaderProgram.cpp @@ -0,0 +1,13 @@ +#include "MyBatchTestShaderProgram.h" + +#include "Util.h" + +MyBatchTestShaderProgram::MyBatchTestShaderProgram() + // TEMP Hardcode in the path. (Should Use Relative Path to General Shader Dir) + : m_vertex_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyBatchTestVertexShader.glsl"), VERTEX_SHADER), + m_fragment_shader(Util::load_file("D:\\Development\\C++\\OpenGLEngine\\OpenGLEngine\\MyBatchTestFragmentShader.glsl"), FRAGMENT_SHADER) +{ + attach_shader(m_vertex_shader); + attach_shader(m_fragment_shader); + link(); +} diff --git a/OpenGLEngine/MyBatchTestShaderProgram.h b/OpenGLEngine/MyBatchTestShaderProgram.h new file mode 100644 index 0000000..bf2431a --- /dev/null +++ b/OpenGLEngine/MyBatchTestShaderProgram.h @@ -0,0 +1,37 @@ +#pragma once + +#include "ShaderProgram.h" +#include "Shader.h" +#include "Mesh.h" +#include "Renderable.h" + +class MyBatchTestShaderProgram : public ShaderProgram +{ +public: + struct VertexType + { + VertexType() {} + VertexType(float x, float y, float z) + : x(x), y(y), z(z) + {} + float x; + float y; + float z; + }; + struct ColorType // Try changing to normalized unsigned chars (0-255) for the example + { + float r; + float g; + float b; + float a; + }; + typedef unsigned int IndexType; + typedef Renderable RenderableType; + typedef Mesh MeshType; + + MyBatchTestShaderProgram(); + +private: + Shader m_vertex_shader; + Shader m_fragment_shader; +}; diff --git a/OpenGLEngine/MyBatchTestVertexShader.glsl b/OpenGLEngine/MyBatchTestVertexShader.glsl new file mode 100644 index 0000000..70cbedb --- /dev/null +++ b/OpenGLEngine/MyBatchTestVertexShader.glsl @@ -0,0 +1,10 @@ +#version 400 +layout(location = 0) in vec3 vertex_position; +layout(location = 1) in vec4 vertex_color; + +out vec4 vert_color; +void main() +{ + gl_Position = vec4(vertex_position, 1.0); + vert_color = vertex_color; +} \ No newline at end of file diff --git a/OpenGLEngine/MyObjectOrientedScene.cpp b/OpenGLEngine/MyObjectOrientedScene.cpp index dc61ede..a6a8389 100644 --- a/OpenGLEngine/MyObjectOrientedScene.cpp +++ b/OpenGLEngine/MyObjectOrientedScene.cpp @@ -4,12 +4,12 @@ #include "MeshFactory.h" MyObjectOrientedScene::MyObjectOrientedScene() - : m_shape(MeshFactory::gen( + : m_shape(MeshFactory::gen( DrawMode::DRAW_TRIANGLES, - MyShaderProgram::VertexType(-0.5f, 0.4f, 0.0f), - MyShaderProgram::VertexType(0.5f, 0.4f, 0.0f), - MyShaderProgram::VertexType(-0.8f, -0.4f, 0.0f), - MyShaderProgram::VertexType(0.8f, -0.4f, 0.0f) + MyBatchTestShaderProgram::VertexType(-0.5f, 0.4f, 0.0f), + MyBatchTestShaderProgram::VertexType(0.5f, 0.4f, 0.0f), + MyBatchTestShaderProgram::VertexType(-0.8f, -0.4f, 0.0f), + MyBatchTestShaderProgram::VertexType(0.8f, -0.4f, 0.0f) ), DrawMode::DRAW_TRIANGLES), m_batch(&m_shape, 1, 1) { } @@ -36,7 +36,25 @@ void MyObjectOrientedScene::unuse() void MyObjectOrientedScene::update(float delta_time, clock_t clock) { + float n; + clock_t c = (clock / 10) % 512; + if (c < 256) + { + n = (float)c / 256; + } + else + { + n = (float)(512 - c) / 256; + } + MyBatchTestShaderProgram::ColorType& element = m_batch.get_element(); + element.r = n; + element.g = n; + element.b = n; + element.a = 1.0f; + + // TODO: Make a prerender function or move this to render + m_batch.prerender(); } void MyObjectOrientedScene::render() diff --git a/OpenGLEngine/MyObjectOrientedScene.h b/OpenGLEngine/MyObjectOrientedScene.h index 4a86384..ff1cf31 100644 --- a/OpenGLEngine/MyObjectOrientedScene.h +++ b/OpenGLEngine/MyObjectOrientedScene.h @@ -3,7 +3,7 @@ #include "Scene.h" #include "MyBatch.h" -#include "MyShaderProgram.h" +#include "MyBatchTestShaderProgram.h" class MyObjectOrientedScene : public Scene { @@ -22,6 +22,6 @@ public: void render() override; private: MyBatch m_batch; - MyShaderProgram::RenderableType m_shape; - MyShaderProgram m_shader_program; + MyBatchTestShaderProgram::RenderableType m_shape; + MyBatchTestShaderProgram m_shader_program; }; \ No newline at end of file diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index 783760f..9be5622 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -157,6 +157,7 @@ + @@ -181,6 +182,7 @@ + @@ -195,6 +197,8 @@ + + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index ddf1fc5..7e2c63e 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -78,6 +78,9 @@ Source Files\Example\Scenes + + Source Files + @@ -152,6 +155,9 @@ Header Files + + Header Files + @@ -160,5 +166,11 @@ Source Files\Example\Shader Code + + Source Files\Example\Shader Code + + + Source Files\Example\Shader Code + \ No newline at end of file