aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYann Herklotz <ymherklotz@gmail.com>2017-04-04 21:47:16 +0100
committerYann Herklotz <ymherklotz@gmail.com>2017-04-04 21:47:16 +0100
commit905f72775fa91b0a467f3c0847c60cf0f85a6d80 (patch)
tree5aa86baf8ed06fd4af036d0bb6c0dbefb5498f9f /src
parent55a1e0ad7c9d2661c266b2e767bfcb2f944e859f (diff)
downloadYAGE-905f72775fa91b0a467f3c0847c60cf0f85a6d80.tar.gz
YAGE-905f72775fa91b0a467f3c0847c60cf0f85a6d80.zip
Sprite batching workin
Diffstat (limited to 'src')
-rw-r--r--src/camera2d.cpp6
-rw-r--r--src/inputmanager.cpp24
-rw-r--r--src/sprite.cpp6
-rw-r--r--src/spritebatch.cpp165
-rw-r--r--src/window.cpp13
5 files changed, 182 insertions, 32 deletions
diff --git a/src/camera2d.cpp b/src/camera2d.cpp
index 5dd25bb3..75bbe9c6 100644
--- a/src/camera2d.cpp
+++ b/src/camera2d.cpp
@@ -26,4 +26,10 @@ void Camera2D::update()
}
}
+void Camera2D::move(const glm::vec2 &direction)
+{
+ position_+=direction;
+ matrix_needs_update_=true;
+}
+
} // yage
diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp
new file mode 100644
index 00000000..0bcb35f8
--- /dev/null
+++ b/src/inputmanager.cpp
@@ -0,0 +1,24 @@
+#include "inputmanager.hpp"
+
+namespace yage
+{
+
+void InputManager::keyPressed(unsigned key)
+{
+ key_map_[key]=true;
+}
+
+void InputManager::keyReleased(unsigned key)
+{
+ key_map_[key]=false;
+}
+
+bool InputManager::isKeyPressed(unsigned key) const
+{
+ auto key_index=key_map_.find(key);
+ if(key_index!=key_map_.end())
+ return key_index->second;
+ return false;
+}
+
+}
diff --git a/src/sprite.cpp b/src/sprite.cpp
index 941a680d..010b43a7 100644
--- a/src/sprite.cpp
+++ b/src/sprite.cpp
@@ -62,14 +62,20 @@ void Sprite::draw()
{
glBindTexture(GL_TEXTURE_2D, texture_.id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id_);
+
glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, position));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void *)offsetof(Vertex, color));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, uv));
glDrawArrays(GL_TRIANGLES, 0, 6);
+ glDisableVertexAttribArray(2);
+ glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
diff --git a/src/spritebatch.cpp b/src/spritebatch.cpp
index 1abcc567..8a08ea86 100644
--- a/src/spritebatch.cpp
+++ b/src/spritebatch.cpp
@@ -1,14 +1,30 @@
#include "spritebatch.hpp"
#include <algorithm>
+#include <stdexcept>
namespace yage
{
+const int SpriteBatch::NUM_VERTICES;
+
+Glyph::Glyph(GLuint texture, float depth, const Vertex &top_left, const Vertex &top_right, const Vertex &bottom_right, const Vertex &bottom_left) :
+ texture_(texture),
+ depth_(depth),
+ top_left_(top_left),
+ top_right_(top_right),
+ bottom_right_(bottom_right),
+ bottom_left_(bottom_left)
+{}
+
+RenderBatch::RenderBatch(GLint offset, GLsizei num_vertices, GLuint texture) :
+ offset_(offset),
+ num_vertices_(num_vertices),
+ texture_(texture)
+{}
+
SpriteBatch::SpriteBatch()
-{
- createVertexArray();
-}
+{}
SpriteBatch::~SpriteBatch()
{
@@ -19,48 +35,135 @@ SpriteBatch::~SpriteBatch()
glDeleteVertexArrays(1, &vbo_);
}
+void SpriteBatch::init()
+{
+ createVertexArray();
+}
+
void SpriteBatch::begin()
-{}
+{
+ glyphs_.clear();
+ glyph_ptrs_.clear();
+ render_batches_.clear();
+}
void SpriteBatch::end()
-{}
+{
+ sortGlyphs();
+ createRenderBatches();
+}
void SpriteBatch::draw(const glm::vec4 &destination_rect, const glm::vec4 &uv_rect, GLuint texture, const Color &color, float depth)
{
- Glyph new_glyph;
- new_glyph.texture=texture;
- new_glyph.depth=depth;
-
- new_glyph.top_left.color=color;
- new_glyph.top_left.setPosition(destination_rect.x, destination_rect.y+destination_rect.w);
- new_glyph.top_left.setUv(uv_rect.x, uv_rect.y+uv_rect.w);
-
- new_glyph.top_right.color=color;
- new_glyph.top_right.setPosition(destination_rect.x+destination_rect.z, destination_rect.y+destination_rect.w);
- new_glyph.top_right.setUv(uv_rect.x+uv_rect.z, uv_rect.y+uv_rect.w);
-
- new_glyph.bottom_right.color=color;
- new_glyph.bottom_right.setPosition(destination_rect.x+destination_rect.z, destination_rect.y);
- new_glyph.bottom_right.setUv(uv_rect.x+uv_rect.z, uv_rect.y);
+ Vertex top_left, top_right, bottom_right, bottom_left;
+
+ top_left.color=color;
+ top_left.setPosition(destination_rect.x, destination_rect.y+destination_rect.w);
+ top_left.setUv(uv_rect.x, uv_rect.y+uv_rect.w);
+
+ top_right.color=color;
+ top_right.setPosition(destination_rect.x+destination_rect.z, destination_rect.y+destination_rect.w);
+ top_right.setUv(uv_rect.x+uv_rect.z, uv_rect.y+uv_rect.w);
+
+ bottom_right.color=color;
+ bottom_right.setPosition(destination_rect.x+destination_rect.z, destination_rect.y);
+ bottom_right.setUv(uv_rect.x+uv_rect.z, uv_rect.y);
+
+ bottom_left.color=color;
+ bottom_left.setPosition(destination_rect.x, destination_rect.y);
+ bottom_left.setUv(uv_rect.x, uv_rect.y);
+
+ // deal with fragmenting by creating vector of pointers
+ glyphs_.emplace_back(texture, depth, top_left, top_right, bottom_right, bottom_left);
+ glyph_ptrs_.push_back(&glyphs_.back());
+}
- new_glyph.bottom_right.color=color;
- new_glyph.bottom_right.setPosition(destination_rect.x, destination_rect.y);
- new_glyph.bottom_right.setUv(uv_rect.x, uv_rect.y);
+void SpriteBatch::render()
+{
+ glBindVertexArray(vao_);
+ for(auto &&batch : render_batches_)
+ {
+ glBindTexture(GL_TEXTURE_2D, batch.texture());
+ glDrawArrays(GL_TRIANGLES, batch.offset(), batch.num_vertices());
+ }
+ glBindVertexArray(0);
+}
- // deal with fragmenting
- glyphs_.push_back(new_glyph);
- glyph_ptrs_.push_back(&glyphs_.back());
+void SpriteBatch::createVertexArray()
+{
+ if(vao_==0)
+ {
+ glGenVertexArrays(1, &vao_);
+ if(vao_==0)
+ throw std::runtime_error("glGenVertexArrays failed");
+ }
+ // bind vertex array object
+ glBindVertexArray(vao_);
+
+ if(vbo_==0)
+ {
+ glGenBuffers(1, &vbo_);
+ if(vbo_==0)
+ throw std::runtime_error("glGenBuffers failed");
+ }
+ // bind vertex buffer object
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_);
+
+ // enable vertex attribute arrays
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
+
+ // set the vertex attribute pointers
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, position));
+ glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (void *)offsetof(Vertex, color));
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, uv));
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ // unbind vertex array object
+ glBindVertexArray(0);
}
-void SpriteBatch::renderBatch()
-{}
+void SpriteBatch::createRenderBatches()
+{
+ std::vector<Vertex> vertices;
+ if(glyph_ptrs_.empty())
+ return;
+
+ render_batches_.reserve(glyph_ptrs_.size()*NUM_VERTICES);
+
+ for(int i=0; i<(int)glyph_ptrs_.size(); ++i)
+ {
+ if(i==0 || (i>0 && (glyph_ptrs_[i]->texture()!=glyph_ptrs_[i-1]->texture())))
+ render_batches_.emplace_back(i*NUM_VERTICES, NUM_VERTICES, glyph_ptrs_[i]->texture());
+ else
+ render_batches_.back().offset_+=NUM_VERTICES;
+
+ vertices.push_back(glyph_ptrs_[i]->bottom_left());
+ vertices.push_back(glyph_ptrs_[i]->top_left());
+ vertices.push_back(glyph_ptrs_[i]->top_right());
+ vertices.push_back(glyph_ptrs_[i]->bottom_left());
+ vertices.push_back(glyph_ptrs_[i]->bottom_right());
+ vertices.push_back(glyph_ptrs_[i]->top_right());
+
+ // bind vbo
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_);
+ // orphan the buffer
+ glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), nullptr, GL_DYNAMIC_DRAW);
+ // upload the data
+ glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(Vertex), vertices.data());
+ // unbind buffer
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+}
void SpriteBatch::sortGlyphs()
{
+ // sort using introsort or quicksort
std::sort(glyph_ptrs_.begin(), glyph_ptrs_.end(), [] (Glyph *a, Glyph *b)->bool {
- if(a->depth==b->depth)
- return a->texture<b->texture;
- return a->depth<b->depth;
+ if(a->depth()==b->depth())
+ return a->texture()<b->texture();
+ return a->depth()<b->depth();
});
}
diff --git a/src/window.cpp b/src/window.cpp
index ac2304c9..dc2a743a 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -58,7 +58,10 @@ void Window::create(const std::string &window_name, int width, int height, unsig
// set vsync on instead of custom fps limiting
SDL_GL_SetSwapInterval(1);
// set the clear color to black
- glClearColor(0.f, 0.f, 0.f, 1.f);
+ glClearColor(0.f, 0.5f, 0.f, 1.f);
+ // set alpha blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void Window::swapBuffer()
@@ -66,5 +69,13 @@ void Window::swapBuffer()
// swap the window buffer
SDL_GL_SwapWindow(window_);
}
+
+void Window::clearBuffer()
+{
+ // set the clear depth
+ glClearDepth(1.f);
+ // clears buffer with clear color
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
} // yage