diff --git a/OpenGLEngine/ImageFS.glsl b/OpenGLEngine/ImageFS.glsl new file mode 100644 index 0000000..6f41d5e --- /dev/null +++ b/OpenGLEngine/ImageFS.glsl @@ -0,0 +1,12 @@ +#version 430 +in vec2 fragment_uv; + +out vec4 frag_color; + +layout(location = 4) uniform sampler2D tex; + +void main() +{ + vec4 sampled = texture(tex, fragment_uv); + frag_color = vec4(sampled.xyz, 1.0); +} \ No newline at end of file diff --git a/OpenGLEngine/ImageScene.cpp b/OpenGLEngine/ImageScene.cpp new file mode 100644 index 0000000..15777a5 --- /dev/null +++ b/OpenGLEngine/ImageScene.cpp @@ -0,0 +1,49 @@ +#include "TexturedScene.h" + +#include "stdafx.h" + +#include "GLUtil.h" +#include "MeshFactory.h" + +namespace charcoal +{ + namespace builtin + { + namespace textured + { + void Scene::init() + { + for (auto iter = m_batches.begin(); iter != m_batches.end(); ++iter) + { + Batch& batch = *iter; + batch.init(); + add_prerenderable(&batch); + } + } + + void Scene::use() + { + // TODO: move to glutil + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + } + + void Scene::unuse() + { + + } + + void Scene::render() + { + glutil::clear_screen(); + m_shader_program.use(); + glutil::uniform_matrix(0, m_p_camera->get_world_to_view_matrix()); + glutil::uniform_int(4, 0); // The textured batch uses GL_TEXTURE0 + for (auto iter = m_batches.begin(); iter != m_batches.end(); ++iter) + { + iter->render(); + } + } + } + } +} \ No newline at end of file diff --git a/OpenGLEngine/ImageScene.h b/OpenGLEngine/ImageScene.h new file mode 100644 index 0000000..a10945f --- /dev/null +++ b/OpenGLEngine/ImageScene.h @@ -0,0 +1,36 @@ +#pragma once + +#include "AutoPrerenderingScene.h" +#include "WithCamera.h" +#include "Batched.h" + +#include "SpriteBatch.h" +#include "ImageShaderProgram.h" +#include "ImageTypes.h" + +namespace charcoal +{ + namespace builtin + { + namespace image + { + class Scene : public AutoPrerenderingScene, public WithCamera, public Batched + { + public: + Scene(Application& application) : AutoPrerenderingScene(application) {} + virtual ~Scene() {} + + void init() override; + + void use() override; + + void unuse() override; + + void render() override; + + private: + ShaderProgram m_shader_program; + }; + } + } +} \ No newline at end of file diff --git a/OpenGLEngine/ImageShaderProgram.h b/OpenGLEngine/ImageShaderProgram.h new file mode 100644 index 0000000..67f9c3d --- /dev/null +++ b/OpenGLEngine/ImageShaderProgram.h @@ -0,0 +1,18 @@ +#pragma once + +#include "VertexFragmentShaderProgram.h" + +namespace charcoal +{ + namespace builtin + { + namespace image + { + class ShaderProgram : public VertexFragmentShaderProgram + { + public: + ShaderProgram() : VertexFragmentShaderProgram(SHADER_PATH "ImageVS.glsl", SHADER_PATH "ImageFS.glsl") {} + }; + } + } +} diff --git a/OpenGLEngine/ImageTypes.h b/OpenGLEngine/ImageTypes.h new file mode 100644 index 0000000..b12a904 --- /dev/null +++ b/OpenGLEngine/ImageTypes.h @@ -0,0 +1,19 @@ +#pragma once + +#include "BuiltinTypes.h" + +#include "SpriteBatch.h" + +namespace charcoal +{ + namespace builtin + { + namespace image + { + typedef PTVertex Vertex; + typedef Index Index; + typedef TextureRenderable Renderable; + typedef SpriteBatch Batch; + } + } +} \ No newline at end of file diff --git a/OpenGLEngine/ImageVS.glsl b/OpenGLEngine/ImageVS.glsl new file mode 100644 index 0000000..ebbccf0 --- /dev/null +++ b/OpenGLEngine/ImageVS.glsl @@ -0,0 +1,14 @@ +#version 430 +layout(location = 0) in vec3 vertex_position; +layout(location = 1) in vec2 vertex_uv; +layout(location = 2) in mat4 model_to_world; + +layout(location = 0) uniform mat4 world_to_projection; + +out vec2 fragment_uv; + +void main() +{ + fragment_uv = vertex_uv; + gl_Position = world_to_projection * model_to_world * vec4(vertex_position, 1.0); +} \ No newline at end of file diff --git a/OpenGLEngine/MeshGenerator.h b/OpenGLEngine/MeshGenerator.h index 4c94fcb..5f75c52 100644 --- a/OpenGLEngine/MeshGenerator.h +++ b/OpenGLEngine/MeshGenerator.h @@ -648,6 +648,96 @@ namespace charcoal } // TODO: Mesh* gen_cube(const DrawMode& draw_mode, float width, float height, float depth); + + template + Mesh* gen_rect_pt(const DrawMode& draw_mode, float width, float height, float offset_x = 0.0f, float offset_y = 0.0f) + { + float half_width = width / 2.0f; + float half_height = height / 2.0f; + + Mesh* mesh; + + Position pos0(offset_x - half_width, offset_y - half_width, 0.0f); + Position pos1(offset_x - half_width, offset_y + half_width, 0.0f); + Position pos2(offset_x + half_width, offset_y - half_width, 0.0f); + Position pos3(offset_x + half_width, offset_y + half_width, 0.0f); + + UV uv0(0.0f, 1.0f); + UV uv1(0.0f, 0.0f); + UV uv2(1.0f, 1.0f); + UV uv3(1.0f, 0.0f); + + switch (draw_mode) + { + case DrawMode::DRAW_TRIANGLES: + mesh = MeshFactory::create_mesh(4, 6); + + mesh->vertices[0].set_uv(uv0); + mesh->vertices[1].set_uv(uv1); + mesh->vertices[2].set_uv(uv2); + mesh->vertices[3].set_uv(uv3); + + mesh->vertices[0].set_position(pos0); + mesh->vertices[1].set_position(pos1); + mesh->vertices[2].set_position(pos2); + mesh->vertices[3].set_position(pos3); + + mesh->indices[0] = 1; + mesh->indices[1] = 3; + mesh->indices[2] = 0; + mesh->indices[3] = 0; + mesh->indices[4] = 3; + mesh->indices[5] = 2; + break; + case DrawMode::DRAW_TRIANGLE_STRIP: + mesh = MeshFactory::create_mesh(4, 4); + + mesh->vertices[0].set_uv(uv0); + mesh->vertices[1].set_uv(uv1); + mesh->vertices[2].set_uv(uv2); + mesh->vertices[3].set_uv(uv3); + + mesh->vertices[0].set_position(pos0); + mesh->vertices[1].set_position(pos1); + mesh->vertices[2].set_position(pos2); + mesh->vertices[3].set_position(pos3); + + mesh->indices[0] = 1; + mesh->indices[1] = 3; + mesh->indices[2] = 0; + mesh->indices[3] = 2; + break; + case DrawMode::DRAW_TRIANGLE_FAN: + mesh = MeshFactory::create_mesh(4, 4); + + mesh->vertices[0].set_uv(uv0); + mesh->vertices[1].set_uv(uv1); + mesh->vertices[2].set_uv(uv2); + mesh->vertices[3].set_uv(uv3); + + mesh->vertices[0].set_position(pos0); + mesh->vertices[1].set_position(pos1); + mesh->vertices[2].set_position(pos2); + mesh->vertices[3].set_position(pos3); + + mesh->indices[0] = 1; + mesh->indices[1] = 3; + mesh->indices[2] = 2; + mesh->indices[3] = 0; + break; + case DrawMode::DRAW_POINTS: + case DrawMode::DRAW_LINES: + case DrawMode::DRAW_LINE_STRIP: + case DrawMode::DRAW_LINE_LOOP: + case DrawMode::DRAW_LINE_STRIP_ADJACENCY: + case DrawMode::DRAW_LINES_ADJACENCY: + case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY: + case DrawMode::DRAW_TRIANGLES_ADJACENCY: + case DrawMode::DRAW_PATCHES: + default: + throw EXCEPTION("Unable to gen_rect_pt for current draw mode: " + std::to_string(draw_mode)); + } + } } } } diff --git a/OpenGLEngine/MyApplication.cpp b/OpenGLEngine/MyApplication.cpp index 5fc5da8..2dc5886 100644 --- a/OpenGLEngine/MyApplication.cpp +++ b/OpenGLEngine/MyApplication.cpp @@ -9,7 +9,8 @@ MyApplication::MyApplication(int width, int height) m_builtin_basic_cube_scene(*this), m_builtin_lit_scene(*this), m_builtin_textured_scene(*this), - m_builtin_lit_shadowed_scene(*this) + m_builtin_lit_shadowed_scene(*this), + m_builtin_image_scene(*this) {} void MyApplication::init() @@ -22,6 +23,7 @@ void MyApplication::init() m_builtin_lit_scene.init(); m_builtin_textured_scene.init(); m_builtin_lit_shadowed_scene.init(); + m_builtin_image_scene.init(); m_p_current_scene = &m_basic_scene; m_p_current_scene->use(); @@ -61,6 +63,10 @@ void MyApplication::update(float delta_time, clock_t clock) { swap_scene(&m_builtin_lit_shadowed_scene); } + else if (m_glfw_input_manager.is_key_pressed(GLFW_KEY_9)) + { + swap_scene(&m_builtin_image_scene); + } m_p_current_scene->update(delta_time, clock); } diff --git a/OpenGLEngine/MyApplication.h b/OpenGLEngine/MyApplication.h index 5679e8b..54e5a8e 100644 --- a/OpenGLEngine/MyApplication.h +++ b/OpenGLEngine/MyApplication.h @@ -9,6 +9,7 @@ #include "MyBuiltinLitScene.h" #include "MyBuiltinTexturedScene.h" #include "MyBuiltinLitShadowedScene.h" +#include "MyBuiltinImageScene.h" using namespace charcoal; @@ -40,6 +41,7 @@ private: MyBuiltinCubeScene m_builtin_basic_cube_scene; MyBuiltinLitScene m_builtin_lit_scene; MyBuiltinTexturedScene m_builtin_textured_scene; - MyBuiltinLitShadowedScene m_builtin_lit_shadowed_scene; + MyBuiltinLitShadowedScene m_builtin_lit_shadowed_scene; // Currently a WIP + MyBuiltinImageScene m_builtin_image_scene; }; diff --git a/OpenGLEngine/MyBuiltinImageScene.cpp b/OpenGLEngine/MyBuiltinImageScene.cpp new file mode 100644 index 0000000..1564cec --- /dev/null +++ b/OpenGLEngine/MyBuiltinImageScene.cpp @@ -0,0 +1,62 @@ +#include "MyBuiltinImageScene.h" + +#include "TextureFactory.h" + +#include "MeshGenerator.h" +#include "TextureGenerator.h" + +#include "constants.h" + +MyBuiltinImageScene::MyBuiltinImageScene(Application& application) + : image::Scene(application), + m_image(image_loader::load_file(IMAGE_PATH "uber.png")), + m_image_renderable( + meshgenerator::gen_rect_pt(DRAW_TRIANGLES, (float)m_image.width, (float)m_image.height), + TextureFactory::gen_image_texture(m_image), + texturegenerator::gen_quick_sampler(), + DrawMode::DRAW_TRIANGLES + ), + m_camera(m_screen_size), + m_batch(add_batch(&m_image_renderable, 1)) +{ + add_prerenderable(&m_camera); + set_camera(&m_camera); +} + +void MyBuiltinImageScene::update(float delta_time, clock_t clock) +{ + float brightness; + float radians; + + clock_t c; + const clock_t intervals = 512 * CLOCKS_PER_SEC / 100; + const clock_t half_interval = 256 * CLOCKS_PER_SEC / 100; + c = clock % intervals; + if (c < half_interval) + brightness = (float)c / half_interval; + else + brightness = (float)(intervals - c) / half_interval; + + radians = (float)TAU * c / intervals; + + { + Poseable2D& pose = m_batch.get_pose(0); + // pose.rotate((float)TAU_1_4 * delta_time); TODO + pose.update_position(vec3(3 * (float)cos(radians), 0.0f, 0.0f)); + } + + vec3 camera_translation(0.0f, 0.0f, 0.0f); + + if (m_input_manager.is_key_down(GLFW_KEY_W)) camera_translation.y += 1; + if (m_input_manager.is_key_down(GLFW_KEY_S)) camera_translation.y -= 1; + if (m_input_manager.is_key_down(GLFW_KEY_A)) camera_translation.x -= 1; + if (m_input_manager.is_key_down(GLFW_KEY_D)) camera_translation.x += 1; + + float camera_rotation = 0.0f; + if (m_input_manager.is_key_down(GLFW_KEY_Z)) camera_rotation += 1; + if (m_input_manager.is_key_down(GLFW_KEY_C)) camera_rotation -= 1; + + m_camera.translate(camera_translation * delta_time); + // m_camera.rotate(vec3(0.0f, 0.0f, 1.0f), camera_rotation * (float)TAU_1_8 * delta_time); TODO +} + diff --git a/OpenGLEngine/MyBuiltinImageScene.h b/OpenGLEngine/MyBuiltinImageScene.h new file mode 100644 index 0000000..212c759 --- /dev/null +++ b/OpenGLEngine/MyBuiltinImageScene.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ImageLoader.h" + +#include "ImageScene.h" +#include "BuiltinCamera2D.h" + +using namespace charcoal; +using namespace charcoal::builtin; + +class MyBuiltinImageScene : public image::Scene +{ +public: + MyBuiltinImageScene(Application& application); + + void update(float delta_time, clock_t clock) override; +private: + image_loader::ImageRGBA m_image; + image::Renderable m_image_renderable; + builtin::Camera2D m_camera; + image::Batch& m_batch; +}; \ No newline at end of file diff --git a/OpenGLEngine/MySimple2DScene.h b/OpenGLEngine/MySimple2DScene.h index c09adea..4b8842e 100644 --- a/OpenGLEngine/MySimple2DScene.h +++ b/OpenGLEngine/MySimple2DScene.h @@ -31,5 +31,5 @@ private: MySimpleShaderProgram m_shader_program; MySimpleShaderProgram::RenderableT m_shape; MyBatch m_batch; - Camera2D m_camera; + charcoal::Camera2D m_camera; }; \ No newline at end of file diff --git a/OpenGLEngine/OpenGLEngine.vcxproj b/OpenGLEngine/OpenGLEngine.vcxproj index 33e1c9d..b4bc08d 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj +++ b/OpenGLEngine/OpenGLEngine.vcxproj @@ -91,7 +91,7 @@ true $(ProjectDir)..\include;%(AdditionalIncludeDirectories) NotUsing - SHADER_PATH=R"($(ProjectDir))";%(PreprocessorDefinitions) + SHADER_PATH=R"($(ProjectDir))";IMAGE_PATH=R"($(SolutionDir)images\)";%(PreprocessorDefinitions) @@ -131,7 +131,7 @@ true $(ProjectDir)..\include;%(AdditionalIncludeDirectories) NotUsing - SHADER_PATH=R"($(ProjectDir))";%(PreprocessorDefinitions) + SHADER_PATH=R"($(ProjectDir))";IMAGE_PATH=R"($(SolutionDir)images\)";%(PreprocessorDefinitions) true @@ -159,6 +159,7 @@ + @@ -169,6 +170,7 @@ + @@ -179,10 +181,10 @@ + - NotUsing NotUsing @@ -212,6 +214,9 @@ + + + @@ -222,13 +227,15 @@ + + - + @@ -261,10 +268,13 @@ + + + diff --git a/OpenGLEngine/OpenGLEngine.vcxproj.filters b/OpenGLEngine/OpenGLEngine.vcxproj.filters index 55aeb25..70f0871 100644 --- a/OpenGLEngine/OpenGLEngine.vcxproj.filters +++ b/OpenGLEngine/OpenGLEngine.vcxproj.filters @@ -106,9 +106,6 @@ {2f2c0657-4ba3-4314-86dd-a600f533f746} - - {f3f94b58-31cf-4a57-bc2a-0c3a33a6b9ee} - {fa76cc6e-e866-4987-8263-85abac1ac2c6} @@ -139,6 +136,9 @@ {492583f7-cffd-4d22-82c6-88be804e2f2f} + + {f3f94b58-31cf-4a57-bc2a-0c3a33a6b9ee} + @@ -249,9 +249,15 @@ Source Files\Engine\Plugins\LodePNG - + Source Files\Engine\Baseline + + Source Files\Engine\builtin\Scenes\2D\Image + + + Source Files\Example\Application + @@ -455,9 +461,27 @@ Header Files\Engine\builtin\General - + Header Files\Engine\Baseline + + Header Files\Engine\builtin\General + + + Header Files\Engine\builtin\Scenes\2D\Image + + + Header Files\Engine\builtin\Scenes\2D\Image + + + Header Files\Engine\builtin\General + + + Header Files\Engine\builtin\Scenes\2D\Image + + + Header Files\Example\Application + @@ -496,5 +520,11 @@ Source Files\Engine\builtin\Scenes\Shaders + + Source Files\Engine\builtin\Scenes\Shaders + + + Source Files\Engine\builtin\Scenes\Shaders + \ No newline at end of file diff --git a/OpenGLEngine/Poseable2D.cpp b/OpenGLEngine/Poseable2D.cpp new file mode 100644 index 0000000..c2cb7c7 --- /dev/null +++ b/OpenGLEngine/Poseable2D.cpp @@ -0,0 +1,28 @@ +#include "Poseable2D.h" + +namespace charcoal +{ + Poseable2D::Poseable2D(const vec2& position) : Poseable(vec3(position, 0.0f)) + {} + + void Poseable2D::update_position(const vec2& position) + { + Poseable::update_position(vec3(position, 0.0f)); + } + + void Poseable2D::update_rotation(float angle) + { + Poseable::reset_orientation(); + rotate(angle); + } + + void Poseable2D::translate(const vec2& translation) + { + Poseable::translate(vec3(translation, 0.0f)); + } + + void Poseable2D::rotate(float angle) + { + Poseable::rotate(vec3(0.0f, 0.0f, 1.0f), angle); + } +} diff --git a/OpenGLEngine/Sprite.h b/OpenGLEngine/Poseable2D.h similarity index 74% rename from OpenGLEngine/Sprite.h rename to OpenGLEngine/Poseable2D.h index 8bdb8e4..35b71fc 100644 --- a/OpenGLEngine/Sprite.h +++ b/OpenGLEngine/Poseable2D.h @@ -6,10 +6,11 @@ namespace charcoal { - class Sprite : private Poseable + class Poseable2D : private Poseable { public: - Sprite(const vec2& position = vec2(0.0f, 0.0f)); + // TODO: Implementation?? + Poseable2D(const vec2& position = vec2(0.0f, 0.0f)); void update_position(const vec2& position); void update_rotation(float angle); diff --git a/OpenGLEngine/Poseable2DBatch.h b/OpenGLEngine/Poseable2DBatch.h new file mode 100644 index 0000000..432700c --- /dev/null +++ b/OpenGLEngine/Poseable2DBatch.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Batch.h" +#include "BuiltinBatch.h" +#include "Renderable.h" +#include "Poseable2D.h" + +namespace charcoal +{ + namespace builtin + { + // This has to be made completely seperately in order to avoid the vtable that gets added if Poseable is abstracted between + // 2D and 3D + template > + class Poseable2DBatch : public builtin::Batch + { + public: + Poseable2DBatch( + RenderableT* renderable, + int element_count + ) : Poseable2DBatch(renderable, element_count, element_count) + {} + + Poseable2DBatch( + RenderableT* renderable, + int element_count, + int element_render_count + ) : builtin::Batch(renderable, element_render_count), m_pose_elements(element_count) + {} + + virtual ~Poseable2DBatch() {} + + Poseable2D& get_pose(int index) { return m_pose_elements[index]; } + const Poseable2D& get_pose(int index) const { return m_pose_elements[index]; } + + protected: + void setup_element_buffers() + { + glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch::m_element_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, m_pose_elements.size() * sizeof(Poseable), NULL, GL_STREAM_DRAW); + } + + void 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, charcoal::Batch::m_element_buffers[0]); + glBufferData(GL_ARRAY_BUFFER, m_pose_elements.size() * sizeof(Poseable), NULL, GL_STREAM_DRAW); + glBufferSubData(GL_ARRAY_BUFFER, 0, m_pose_elements.size() * sizeof(Poseable), m_pose_elements.data()); + } + + std::vector m_pose_elements; + }; + } +} \ No newline at end of file diff --git a/OpenGLEngine/PoseableBatch.h b/OpenGLEngine/PoseableBatch.h index 1635b2f..b3e84bc 100644 --- a/OpenGLEngine/PoseableBatch.h +++ b/OpenGLEngine/PoseableBatch.h @@ -9,6 +9,7 @@ namespace charcoal { namespace builtin { + // Note: If anything is changed in this file, it must also be changed in Poseable2DBatch template > class PoseableBatch : public builtin::Batch { diff --git a/OpenGLEngine/Sprite.cpp b/OpenGLEngine/Sprite.cpp deleted file mode 100644 index cc7b528..0000000 --- a/OpenGLEngine/Sprite.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "Sprite.h" - -namespace charcoal -{ - Sprite::Sprite(const vec2& position) : Poseable(vec3(position, 0.0f)) - {} - - void Sprite::update_position(const vec2& position) - { - Poseable::update_position(vec3(position, 0.0f)); - } - - void Sprite::update_rotation(float angle) - { - Poseable::reset_orientation(); - rotate(angle); - } - - void Sprite::translate(const vec2& translation) - { - Poseable::translate(vec3(translation, 0.0f)); - } - - void Sprite::rotate(float angle) - { - Poseable::rotate(vec3(0.0f, 0.0f, 1.0f), angle); - } -} \ No newline at end of file diff --git a/OpenGLEngine/SpriteBatch.h b/OpenGLEngine/SpriteBatch.h index 2315fcf..00a849d 100644 --- a/OpenGLEngine/SpriteBatch.h +++ b/OpenGLEngine/SpriteBatch.h @@ -1,26 +1,67 @@ #pragma once -#include "BuiltinBatch.h" +#include "Poseable2D.h" +#include "TextureRenderable.h" +#include "Poseable2DBatch.h" namespace charcoal { namespace builtin { - template > - class SpriteBatch : public builtin::Batch + template + class SpriteBatch : public Poseable2DBatch > { + // Note: This is VERY similar to builtin::textured::Batch + // TODO: Use Poseable2D for each sprite's position + // TODO: Have a texture + // Note: Uses GL_TEXTURE0. The uniform for this texture should be set in the scene before rendering. SpriteBatch( - RenderableT* renderable, + TextureRenderable* renderable, int element_count - ) : PoseableBatch(renderable, element_count, element_count) + ) : Poseable2DBatch >(renderable, element_count) {} SpriteBatch( - RenderableT* renderable, + TextureRenderable* renderable, int element_count, int element_render_count - ) : builtin::Batch(renderable, element_render_count), m_pose_elements(element_count) + ) : Poseable2DBatch >(renderable, element_count, element_render_count) {} + + void preprender() const override + { + // Note: Uses GL_TEXTURE0. The uniform for this texture should be set in the scene. + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, charcoal::Batch >::m_p_renderable->get_texture()->get_texture()); + glBindSampler(0, charcoal::Batch >::m_p_renderable->get_sampler()->get_sampler()); + } + + protected: + void setup_vao() override + { + glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch >::m_vertex_vbo); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + // TODO: Figure out how to do this without offsetof :( + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexType), (void*)offsetof(VertexType, position)); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexType), (void*)offsetof(VertexType, uv)); + glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch >::m_element_buffers[0]); + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); + glEnableVertexAttribArray(5); + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable2D), (void*)(0 * sizeof(vec4))); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable2D), (void*)(1 * sizeof(vec4))); + glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable2D), (void*)(2 * sizeof(vec4))); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(Poseable2D), (void*)(3 * sizeof(vec4))); + + glVertexAttribDivisor(0, 0); // Send the mesh data once + glVertexAttribDivisor(1, 0); // Send the mesh data once + glVertexAttribDivisor(2, 1); // Send the offset data for each instance drawn + glVertexAttribDivisor(3, 1); // Send the offset data for each instance drawn + glVertexAttribDivisor(4, 1); // Send the offset data for each instance drawn + glVertexAttribDivisor(5, 1); // Send the offset data for each instance drawn + } }; } } diff --git a/OpenGLEngine/TextureFactory.h b/OpenGLEngine/TextureFactory.h index e4d6806..2a15d9e 100644 --- a/OpenGLEngine/TextureFactory.h +++ b/OpenGLEngine/TextureFactory.h @@ -2,6 +2,8 @@ #include +#include "ImageLoader.h" + #include "Texture.h" #include "Sampler.h" @@ -30,6 +32,11 @@ namespace charcoal return &m_textures.back(); } + static Texture* gen_image_texture(const image_loader::ImageRGBA& image) + { + return gen_texture(Texture::Format::RGBA, Texture::Type::UNSIGNED_BYTE, image.width, image.height, image.data, Texture::InternalFormat::RGBA); + } + static Sampler* gen_sampler( Sampler::Wrap wrap_s, Sampler::Wrap wrap_t, diff --git a/OpenGLEngine/TexturedScene.cpp b/OpenGLEngine/TexturedScene.cpp index 15777a5..c4f03a4 100644 --- a/OpenGLEngine/TexturedScene.cpp +++ b/OpenGLEngine/TexturedScene.cpp @@ -38,7 +38,7 @@ namespace charcoal glutil::clear_screen(); m_shader_program.use(); glutil::uniform_matrix(0, m_p_camera->get_world_to_view_matrix()); - glutil::uniform_int(4, 0); // The textured batch uses GL_TEXTURE0 + glutil::uniform_int(4, 0); // Sprite batches all use GL_TEXTURE0 so set this to 0 for (auto iter = m_batches.begin(); iter != m_batches.end(); ++iter) { iter->render(); diff --git a/OpenGLEngine/TexturedScene.h b/OpenGLEngine/TexturedScene.h index 1f47742..98456d0 100644 --- a/OpenGLEngine/TexturedScene.h +++ b/OpenGLEngine/TexturedScene.h @@ -4,7 +4,6 @@ #include "AutoPrerenderingScene.h" -#include "BuiltinTypes.h" #include "Camera.h" #include "Batched.h" #include "TexturedBatch.h" diff --git a/OpenGLEngine/WithCamera.h b/OpenGLEngine/WithCamera.h new file mode 100644 index 0000000..a8916ee --- /dev/null +++ b/OpenGLEngine/WithCamera.h @@ -0,0 +1,20 @@ +#pragma once + +#include "Camera.h" + +namespace charcoal +{ + namespace builtin + { + class WithCamera + { + protected: + void set_camera(Camera* camera) { m_p_camera = camera; } + + Camera* get_camera() { return m_p_camera; } + + private: + Camera* m_p_camera = nullptr; + }; + } +} \ No newline at end of file diff --git a/images/uber.png b/images/uber.png new file mode 100644 index 0000000..d1522ed Binary files /dev/null and b/images/uber.png differ