diff --git a/CharcoalBuiltin/BasicBatch.h b/CharcoalBuiltin/BasicBatch.h
index 9915ceb..63d50a7 100644
--- a/CharcoalBuiltin/BasicBatch.h
+++ b/CharcoalBuiltin/BasicBatch.h
@@ -17,7 +17,9 @@ namespace charcoal
void setup_vao_vertex() override
{
glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
+
glEnableVertexAttribArray(0);
+
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL);
glVertexAttribDivisor(0, 0);
diff --git a/CharcoalBuiltin/CharcoalBuiltin.vcxproj b/CharcoalBuiltin/CharcoalBuiltin.vcxproj
index 2aa36e8..72111cb 100644
--- a/CharcoalBuiltin/CharcoalBuiltin.vcxproj
+++ b/CharcoalBuiltin/CharcoalBuiltin.vcxproj
@@ -159,6 +159,11 @@ copy "$(ProjectDir)*.h" "$(SolutionDir)include\charcoal-builtin\"
+
+
+
+
+
diff --git a/CharcoalBuiltin/CharcoalBuiltin.vcxproj.filters b/CharcoalBuiltin/CharcoalBuiltin.vcxproj.filters
index a3dc84d..c6659f7 100644
--- a/CharcoalBuiltin/CharcoalBuiltin.vcxproj.filters
+++ b/CharcoalBuiltin/CharcoalBuiltin.vcxproj.filters
@@ -25,6 +25,9 @@
{1dbc28a4-b52f-4171-a385-79490dfa9b0a}
+
+ {a0a4d461-a490-40ce-bc57-22c47460f60e}
+
@@ -89,5 +92,20 @@
Header Files\General
+
+ Header Files\Pipelines\Textured
+
+
+ Header Files\Pipelines\Textured
+
+
+ Header Files\Pipelines\Textured
+
+
+ Header Files\Pipelines\Textured
+
+
+ Header Files\Pipelines\Textured
+
\ No newline at end of file
diff --git a/CharcoalBuiltin/TexturedBatch.h b/CharcoalBuiltin/TexturedBatch.h
new file mode 100644
index 0000000..b43f515
--- /dev/null
+++ b/CharcoalBuiltin/TexturedBatch.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "TexturedTypes.h"
+#include "TexturedRenderable.h"
+#include "PoseableBatch.h"
+
+namespace charcoal
+{
+ namespace builtin
+ {
+ namespace textured
+ {
+ class Batch : public PoseableBatch
+ {
+ public:
+ using PoseableBatch::PoseableBatch;
+ protected:
+ void setup_vao_vertex() override
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertex_vbo);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, uv));
+
+ glVertexAttribDivisor(0, 0);
+ glVertexAttribDivisor(1, 0);
+ }
+
+ void preprender() const override {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_p_renderable->get_texture()->get_texture());
+ glBindSampler(0, m_p_renderable->get_sampler()->get_sampler());
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/CharcoalBuiltin/TexturedPipeline.h b/CharcoalBuiltin/TexturedPipeline.h
new file mode 100644
index 0000000..2d0d3cf
--- /dev/null
+++ b/CharcoalBuiltin/TexturedPipeline.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "GLUtil.h"
+#include "BuiltinPipeline.h"
+#include "WithCamera.h"
+#include "TexturedShaderProgram.h"
+#include "TexturedBatch.h"
+
+namespace charcoal
+{
+ namespace builtin
+ {
+ namespace textured
+ {
+ class Pipeline : public builtin::Pipeline, public WithCamera
+ {
+ public:
+ void prepare_opengl() override
+ {
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ }
+
+ void prepare_uniforms() override
+ {
+ glutil::uniform_matrix(0, get_camera()->get_world_to_view_matrix());
+ }
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/CharcoalBuiltin/TexturedRenderable.h b/CharcoalBuiltin/TexturedRenderable.h
new file mode 100644
index 0000000..a4fd467
--- /dev/null
+++ b/CharcoalBuiltin/TexturedRenderable.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "TexturedTypes.h"
+
+namespace charcoal
+{
+ namespace builtin
+ {
+ namespace textured
+ {
+ class Renderable : public RenderableT
+ {
+ public:
+ Renderable(
+ const Mesh* mesh,
+ const DrawMode& draw_mode,
+ Texture* texture,
+ Sampler* sampler
+ )
+ : RenderableT(mesh, draw_mode),
+ m_p_texture(texture),
+ m_p_sampler(sampler)
+ {}
+
+ Texture* get_texture() const { return m_p_texture; }
+ Sampler* get_sampler() const { return m_p_sampler; }
+
+ private:
+ Texture* m_p_texture;
+ Sampler* m_p_sampler;
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/CharcoalBuiltin/TexturedShaderProgram.h b/CharcoalBuiltin/TexturedShaderProgram.h
new file mode 100644
index 0000000..00d6ef5
--- /dev/null
+++ b/CharcoalBuiltin/TexturedShaderProgram.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+
+namespace charcoal
+{
+ namespace builtin
+ {
+ namespace textured
+ {
+ class ShaderProgram : public VertexFragmentShaderProgram
+ {
+ public:
+ ShaderProgram() : VertexFragmentShaderProgram(SHADER_PATH "TexturedVS.glsl", SHADER_PATH "TexturedFS.glsl") {}
+ };
+ }
+ }
+}
diff --git a/CharcoalBuiltin/TexturedTypes.h b/CharcoalBuiltin/TexturedTypes.h
new file mode 100644
index 0000000..ab6bc32
--- /dev/null
+++ b/CharcoalBuiltin/TexturedTypes.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "BuiltinTypes.h"
+
+namespace charcoal
+{
+ namespace builtin
+ {
+ namespace textured
+ {
+ typedef PTVertex Vertex;
+ typedef Index Index;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Example/Example.vcxproj b/Example/Example.vcxproj
index 6fda776..306d8ef 100644
--- a/Example/Example.vcxproj
+++ b/Example/Example.vcxproj
@@ -24,6 +24,7 @@
+
@@ -34,6 +35,7 @@
+
diff --git a/Example/Example.vcxproj.filters b/Example/Example.vcxproj.filters
index 7f8e50a..769100f 100644
--- a/Example/Example.vcxproj.filters
+++ b/Example/Example.vcxproj.filters
@@ -39,6 +39,9 @@
Source Files
+
+ Source Files
+
@@ -68,5 +71,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/Example/MyApplication.cpp b/Example/MyApplication.cpp
index c3cc5b2..6521907 100644
--- a/Example/MyApplication.cpp
+++ b/Example/MyApplication.cpp
@@ -6,7 +6,8 @@ MyApplication::MyApplication(int width, int height)
m_simple_2d_scene(*this),
m_simple_3d_scene(*this),
m_simple_cube_scene(*this),
- m_builtin_basic_cube_scene(*this)
+ m_builtin_basic_cube_scene(*this),
+ m_builtin_textured_scene(*this)
{}
void MyApplication::init()
@@ -16,6 +17,7 @@ void MyApplication::init()
m_simple_3d_scene.init();
m_simple_cube_scene.init();
m_builtin_basic_cube_scene.init();
+ m_builtin_textured_scene.init();
m_p_current_scene = &m_basic_scene;
m_p_current_scene->use();
@@ -43,6 +45,10 @@ void MyApplication::update(float delta_time, clock_t clock)
{
swap_scene(&m_builtin_basic_cube_scene);
}
+ else if (m_glfw_input_manager.is_key_pressed(GLFW_KEY_6))
+ {
+ swap_scene(&m_builtin_textured_scene);
+ }
m_p_current_scene->update(delta_time, clock);
}
diff --git a/Example/MyApplication.h b/Example/MyApplication.h
index 9e81b3c..5b8d32a 100644
--- a/Example/MyApplication.h
+++ b/Example/MyApplication.h
@@ -8,6 +8,7 @@
#include "MySimple3DScene.h"
#include "MySimpleCubeScene.h"
#include "MyBuiltinCubeScene.h"
+#include "MyBuiltinTexturedScene.h"
using namespace charcoal;
@@ -36,5 +37,6 @@ private:
MySimple3DScene m_simple_3d_scene;
MySimpleCubeScene m_simple_cube_scene;
MyBuiltinCubeScene m_builtin_basic_cube_scene;
+ MyBuiltinTexturedScene m_builtin_textured_scene;
};
diff --git a/Example/MyBuiltinCubeScene.h b/Example/MyBuiltinCubeScene.h
index 7a64136..ddb7dfa 100644
--- a/Example/MyBuiltinCubeScene.h
+++ b/Example/MyBuiltinCubeScene.h
@@ -1,7 +1,7 @@
#pragma once
#include
-#include
+#include
#include
#include
diff --git a/Example/MyBuiltinTexturedScene.cpp b/Example/MyBuiltinTexturedScene.cpp
new file mode 100644
index 0000000..e06ce1c
--- /dev/null
+++ b/Example/MyBuiltinTexturedScene.cpp
@@ -0,0 +1,98 @@
+#include "MyBuiltinTexturedScene.h"
+
+#include
+#include
+
+#include
+#include
+#include
+
+MyBuiltinTexturedScene::MyBuiltinTexturedScene(Application& application)
+ : Scene(application),
+ m_sprite_image(image_loader::load_file(IMAGE_PATH "uber.png")),
+ m_cube(
+ meshgenerator::gen_cube_pt(DRAW_TRIANGLES, 2.0f, 2.0f, 2.0f),
+ DRAW_TRIANGLES,
+ texturegenerator::gen_quick_cube_texture(),
+ texturegenerator::gen_quick_sampler()
+ ),
+ m_sprite(
+ meshgenerator::gen_rect_pt(DRAW_TRIANGLES, 2.0f, 2.0f),
+ DRAW_TRIANGLES,
+ TextureFactory::gen_image_texture(m_sprite_image),
+ texturegenerator::gen_quick_sampler()
+ ),
+ m_camera((float)TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f)),
+ m_cube_batch(&m_cube, 2),
+ m_sprite_batch(&m_sprite, 1)
+{
+ m_pipeline.add_batch(&m_cube_batch);
+ m_pipeline.add_batch(&m_sprite_batch);
+ m_pipeline.set_camera(&m_camera);
+}
+
+void MyBuiltinTexturedScene::init()
+{
+ m_cube_batch.init();
+ m_sprite_batch.init();
+}
+
+void MyBuiltinTexturedScene::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;
+
+ m_cube_pose_a.rotate(glm::normalize(vec3(1.0f, 1.0f, 0.0f)), (float)TAU_1_2 * delta_time);
+ m_cube_pose_a.update_position(vec3(3 * (float)cos(radians), 1.0f, 0.0f));
+
+ m_cube_pose_b.rotate(glm::normalize(vec3(1.0f, 1.0f, 0.0f)), (float)TAU_1_2 * delta_time);
+ m_cube_pose_b.update_position(vec3(-3 * (float)cos(radians), -1.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;
+ if (m_input_manager.is_key_down(GLFW_KEY_Q)) camera_translation.z -= 1;
+ if (m_input_manager.is_key_down(GLFW_KEY_E)) camera_translation.z += 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, 1.0f, 0.0f), camera_rotation * (float)TAU_1_8 * delta_time);
+
+ m_cube_batch.reset_rendered();
+ m_cube_batch.add_rendered(m_cube_pose_a);
+ m_cube_batch.add_rendered(m_cube_pose_b);
+
+ m_sprite_batch.reset_rendered();
+ m_sprite_batch.add_rendered(m_sprite_pose);
+}
+
+void MyBuiltinTexturedScene::prerender()
+{
+ m_camera.prerender();
+ m_cube_batch.prerender();
+ m_sprite_batch.prerender();
+}
+
+void MyBuiltinTexturedScene::render()
+{
+ glutil::clear_screen();
+ m_pipeline.render();
+}
+
diff --git a/Example/MyBuiltinTexturedScene.h b/Example/MyBuiltinTexturedScene.h
new file mode 100644
index 0000000..1d0841b
--- /dev/null
+++ b/Example/MyBuiltinTexturedScene.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+
+
+using namespace charcoal;
+using namespace charcoal::builtin;
+
+class MyBuiltinTexturedScene : public Scene
+{
+public:
+ MyBuiltinTexturedScene(Application& application);
+
+ void init() override;
+
+ void use() override {}
+
+ void unuse() override {}
+
+ void update(float delta_time, clock_t clock) override;
+
+ void prerender() override;
+
+ void render() override;
+
+private:
+ image_loader::ImageRGBA m_sprite_image;
+
+ textured::Renderable m_cube;
+ textured::Renderable m_sprite;
+ builtin::Camera3D m_camera;
+
+ textured::Batch m_cube_batch;
+ textured::Batch m_sprite_batch;
+
+ textured::Pipeline m_pipeline;
+
+ Poseable m_cube_pose_a;
+ Poseable m_cube_pose_b;
+
+ Poseable m_sprite_pose;
+};
\ No newline at end of file