Almost able to render the image

Added image scene to render an image in a scene. There is also now
a testing image that is an uber meme. Currently the problem is
that the spritebatch cannot use the offsetof macro because it is a
templated class. Possible solutions to this are changing it to be
specifyable or implemented per vertex type as the other batches
have been.
This commit is contained in:
elipzer 2018-10-09 11:42:17 -04:00
parent a8abb4afc9
commit b7456401e0
25 changed files with 544 additions and 51 deletions

12
OpenGLEngine/ImageFS.glsl Normal file
View File

@ -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);
}

View File

@ -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();
}
}
}
}
}

36
OpenGLEngine/ImageScene.h Normal file
View File

@ -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<Renderable, Batch>
{
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;
};
}
}
}

View File

@ -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") {}
};
}
}
}

19
OpenGLEngine/ImageTypes.h Normal file
View File

@ -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<Vertex, Index> Renderable;
typedef SpriteBatch<Vertex, Index> Batch;
}
}
}

14
OpenGLEngine/ImageVS.glsl Normal file
View File

@ -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);
}

View File

@ -648,6 +648,96 @@ namespace charcoal
}
// TODO: Mesh<PNTVertex, Index>* gen_cube(const DrawMode& draw_mode, float width, float height, float depth);
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* 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<VertexType, IndexType>* 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<VertexType, IndexType>::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<VertexType, IndexType>::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<VertexType, IndexType>::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));
}
}
}
}
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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<image::Vertex, image::Index>(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
}

View File

@ -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;
};

View File

@ -31,5 +31,5 @@ private:
MySimpleShaderProgram m_shader_program;
MySimpleShaderProgram::RenderableT m_shape;
MyBatch m_batch;
Camera2D m_camera;
charcoal::Camera2D m_camera;
};

View File

@ -91,7 +91,7 @@
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>SHADER_PATH=R"($(ProjectDir))";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SHADER_PATH=R"($(ProjectDir))";IMAGE_PATH=R"($(SolutionDir)images\)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link />
<PostBuildEvent>
@ -131,7 +131,7 @@
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions>SHADER_PATH=R"($(ProjectDir))";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SHADER_PATH=R"($(ProjectDir))";IMAGE_PATH=R"($(SolutionDir)images\)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
@ -159,6 +159,7 @@
<ClCompile Include="Camera3D.cpp" />
<ClCompile Include="FPS.cpp" />
<ClCompile Include="ImageLoader.cpp" />
<ClCompile Include="ImageScene.cpp" />
<ClCompile Include="LitBatch.cpp" />
<ClCompile Include="LitScene.cpp" />
<ClCompile Include="LitShadowedBatch.cpp" />
@ -169,6 +170,7 @@
<ClCompile Include="GLUtil.cpp" />
<ClCompile Include="InputManager.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MyBuiltinImageScene.cpp" />
<ClCompile Include="MyBuiltinLitScene.cpp" />
<ClCompile Include="MyBuiltinLitShadowedScene.cpp" />
<ClCompile Include="MyBuiltinTexturedScene.cpp" />
@ -179,10 +181,10 @@
<ClCompile Include="MySimple2DScene.cpp" />
<ClCompile Include="MyBasicScene.cpp" />
<ClCompile Include="Poseable.cpp" />
<ClCompile Include="Poseable2D.cpp" />
<ClCompile Include="Shader.cpp" />
<ClCompile Include="ShaderProgram.cpp" />
<ClCompile Include="Sampler.cpp" />
<ClCompile Include="Sprite.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
@ -212,6 +214,9 @@
<ClInclude Include="Exception.h" />
<ClInclude Include="FPS.h" />
<ClInclude Include="ImageLoader.h" />
<ClInclude Include="ImageScene.h" />
<ClInclude Include="ImageShaderProgram.h" />
<ClInclude Include="ImageTypes.h" />
<ClInclude Include="LitBatch.h" />
<ClInclude Include="LitScene.h" />
<ClInclude Include="LitShaderProgram.h" />
@ -222,13 +227,15 @@
<ClInclude Include="LitTypes.h" />
<ClInclude Include="lodepng.h" />
<ClInclude Include="MyBuiltinCubeScene.h" />
<ClInclude Include="MyBuiltinImageScene.h" />
<ClInclude Include="MyBuiltinLitScene.h" />
<ClInclude Include="MyBuiltinLitShadowedScene.h" />
<ClInclude Include="MyBuiltinTexturedScene.h" />
<ClInclude Include="Poseable2DBatch.h" />
<ClInclude Include="PoseableBatch.h" />
<ClInclude Include="Prerenderable.h" />
<ClInclude Include="Sampler.h" />
<ClInclude Include="Sprite.h" />
<ClInclude Include="Poseable2D.h" />
<ClInclude Include="SpriteBatch.h" />
<ClInclude Include="Texture.h" />
<ClInclude Include="TexturedBatch.h" />
@ -261,10 +268,13 @@
<ClInclude Include="stdafx.h" />
<ClInclude Include="Util.h" />
<ClInclude Include="BuiltinTypes.h" />
<ClInclude Include="WithCamera.h" />
</ItemGroup>
<ItemGroup>
<None Include="BasicFS.glsl" />
<None Include="BasicVS.glsl" />
<None Include="ImageFS.glsl" />
<None Include="ImageVS.glsl" />
<None Include="LitShadowedFS.glsl" />
<None Include="LitShadowedVS.glsl" />
<None Include="MySimpleFS.glsl" />

View File

@ -106,9 +106,6 @@
<Filter Include="Header Files\Engine\builtin\Scenes\3D\LitShadowed">
<UniqueIdentifier>{2f2c0657-4ba3-4314-86dd-a600f533f746}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Engine\builtin\Scenes\3D\Basic">
<UniqueIdentifier>{f3f94b58-31cf-4a57-bc2a-0c3a33a6b9ee}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Engine\builtin\Scenes\3D\Lit">
<UniqueIdentifier>{fa76cc6e-e866-4987-8263-85abac1ac2c6}</UniqueIdentifier>
</Filter>
@ -139,6 +136,9 @@
<Filter Include="Source Files\Engine\builtin\Scenes\2D\Image">
<UniqueIdentifier>{492583f7-cffd-4d22-82c6-88be804e2f2f}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Engine\builtin\Scenes\3D\Basic">
<UniqueIdentifier>{f3f94b58-31cf-4a57-bc2a-0c3a33a6b9ee}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
@ -249,9 +249,15 @@
<ClCompile Include="lodepng.cpp">
<Filter>Source Files\Engine\Plugins\LodePNG</Filter>
</ClCompile>
<ClCompile Include="Sprite.cpp">
<ClCompile Include="Poseable2D.cpp">
<Filter>Source Files\Engine\Baseline</Filter>
</ClCompile>
<ClCompile Include="ImageScene.cpp">
<Filter>Source Files\Engine\builtin\Scenes\2D\Image</Filter>
</ClCompile>
<ClCompile Include="MyBuiltinImageScene.cpp">
<Filter>Source Files\Example\Application</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Application.h">
@ -455,9 +461,27 @@
<ClInclude Include="SpriteBatch.h">
<Filter>Header Files\Engine\builtin\General</Filter>
</ClInclude>
<ClInclude Include="Sprite.h">
<ClInclude Include="Poseable2D.h">
<Filter>Header Files\Engine\Baseline</Filter>
</ClInclude>
<ClInclude Include="Poseable2DBatch.h">
<Filter>Header Files\Engine\builtin\General</Filter>
</ClInclude>
<ClInclude Include="ImageScene.h">
<Filter>Header Files\Engine\builtin\Scenes\2D\Image</Filter>
</ClInclude>
<ClInclude Include="ImageTypes.h">
<Filter>Header Files\Engine\builtin\Scenes\2D\Image</Filter>
</ClInclude>
<ClInclude Include="WithCamera.h">
<Filter>Header Files\Engine\builtin\General</Filter>
</ClInclude>
<ClInclude Include="ImageShaderProgram.h">
<Filter>Header Files\Engine\builtin\Scenes\2D\Image</Filter>
</ClInclude>
<ClInclude Include="MyBuiltinImageScene.h">
<Filter>Header Files\Example\Application</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="MySimpleVS.glsl">
@ -496,5 +520,11 @@
<None Include="LitShadowedVS.glsl">
<Filter>Source Files\Engine\builtin\Scenes\Shaders</Filter>
</None>
<None Include="ImageVS.glsl">
<Filter>Source Files\Engine\builtin\Scenes\Shaders</Filter>
</None>
<None Include="ImageFS.glsl">
<Filter>Source Files\Engine\builtin\Scenes\Shaders</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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 <typename VertexType, typename IndexType, typename RenderableT = RenderableT<VertexType, IndexType> >
class Poseable2DBatch : public builtin::Batch<VertexType, IndexType, 1, RenderableT>
{
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<VertexType, IndexType, 1, RenderableT>(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<VertexType, IndexType, 1, RenderableT>::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<VertexType, IndexType, 1, RenderableT>::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<Poseable2D> m_pose_elements;
};
}
}

View File

@ -9,6 +9,7 @@ namespace charcoal
{
namespace builtin
{
// Note: If anything is changed in this file, it must also be changed in Poseable2DBatch
template <typename VertexType, typename IndexType, typename RenderableT = RenderableT<VertexType, IndexType> >
class PoseableBatch : public builtin::Batch<VertexType, IndexType, 1, RenderableT>
{

View File

@ -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);
}
}

View File

@ -1,26 +1,67 @@
#pragma once
#include "BuiltinBatch.h"
#include "Poseable2D.h"
#include "TextureRenderable.h"
#include "Poseable2DBatch.h"
namespace charcoal
{
namespace builtin
{
template <typename VertexType, typename IndexType, typename RenderableT = RenderableT<VertexType, IndexType> >
class SpriteBatch : public builtin::Batch<VertexType, IndexType, 1, RenderableT>
template <typename VertexType, typename IndexType>
class SpriteBatch : public Poseable2DBatch<VertexType, IndexType, TextureRenderable<VertexType, IndexType> >
{
// 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<VertexType, IndexType>* renderable,
int element_count
) : PoseableBatch(renderable, element_count, element_count)
) : Poseable2DBatch<VertexType, IndexType, TextureRenderable<VertexType, IndexType> >(renderable, element_count)
{}
SpriteBatch(
RenderableT* renderable,
TextureRenderable<VertexType, IndexType>* renderable,
int element_count,
int element_render_count
) : builtin::Batch<VertexType, IndexType, 1, RenderableT>(renderable, element_render_count), m_pose_elements(element_count)
) : Poseable2DBatch<VertexType, IndexType, TextureRenderable<VertexType, IndexType> >(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<VertexType, IndexType, 1, TextureRenderable<VertexType, IndexType> >::m_p_renderable->get_texture()->get_texture());
glBindSampler(0, charcoal::Batch<VertexType, IndexType, 1, TextureRenderable<VertexType, IndexType> >::m_p_renderable->get_sampler()->get_sampler());
}
protected:
void setup_vao() override
{
glBindBuffer(GL_ARRAY_BUFFER, charcoal::Batch<VertexType, IndexType, 1, TextureRenderable<VertexType, IndexType> >::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<VertexType, IndexType, 1, TextureRenderable<VertexType, IndexType> >::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
}
};
}
}

View File

@ -2,6 +2,8 @@
#include <vector>
#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,

View File

@ -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();

View File

@ -4,7 +4,6 @@
#include "AutoPrerenderingScene.h"
#include "BuiltinTypes.h"
#include "Camera.h"
#include "Batched.h"
#include "TexturedBatch.h"

20
OpenGLEngine/WithCamera.h Normal file
View File

@ -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;
};
}
}

BIN
images/uber.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB