Skip to content

Instantly share code, notes, and snippets.

@DCubix
Created December 2, 2016 19:57
Show Gist options
  • Save DCubix/40f16233afda59939ea8a1b31918f010 to your computer and use it in GitHub Desktop.
Save DCubix/40f16233afda59939ea8a1b31918f010 to your computer and use it in GitHub Desktop.
/*
* The MIT License
*
* Copyright 2016 twisterge.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* File: SpriteBatch.cpp
* Author: twisterge
*
* Created on November 30, 2016, 10:39 AM
*/
#include <vector>
#include "SpriteBatch.h"
SpriteBatch::SpriteBatch(int width, int height) {
glGenBuffers(1, &m_vbo);
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, SB_BUFFER_SIZE, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glVertexAttribPointer(0, 3, GL_FLOAT, false, SB_VERTEX_SIZE, (void*) 0);
glVertexAttribPointer(1, 2, GL_FLOAT, false, SB_VERTEX_SIZE, (void*)12);
glVertexAttribPointer(2, 4, GL_FLOAT, true, SB_VERTEX_SIZE, (void*)20);
glBindVertexArray(0);
Str vss =
"#version 120\n"
"attribute vec3 position;\n"
"attribute vec2 uv;\n"
"attribute vec4 color;\n"
"uniform mat4 projection;\n"
"void main() {\n"
" gl_Position = projection * vec4(position, 1.0);\n"
"}";
Str fss =
"#version 120\n"
"void main() {\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}";
m_default = new Shader(vss, fss);
model.identity();
projection = Matrix4f::createOrtho(0, width, height, 0, -1, 1);
m_drawing = false;
}
void SpriteBatch::Begin() {
if (!m_drawing) {
m_drawing = true;
for (auto it = m_sprites.begin(); it != m_sprites.end(); ++it) {
delete *it;
}
for (auto it = m_batches.begin(); it != m_batches.end(); ++it) {
delete *it;
}
m_sprites.clear();
m_batches.clear();
}
}
void SpriteBatch::End() {
if (m_drawing) {
if (m_sprites.size() == 0) {
m_drawing = false;
return;
}
std::vector<Vertex> verts;
verts.resize(m_sprites.size() * 6);
uint offset = 0, i = 0;
for (auto it = m_sprites.begin(); it != m_sprites.end(); ++it) {
Sprite* spr = *it;
RenderBatch* b = new RenderBatch();
b->depth = spr->depth;
b->diffuse = spr->diffuse;
b->normal = spr->normal;
b->vertex_count = 6;
b->offset = offset;
m_batches.push_back(b);
verts[i++] = spr->v1;
verts[i++] = spr->v4;
verts[i++] = spr->v3;
verts[i++] = spr->v3;
verts[i++] = spr->v2;
verts[i++] = spr->v1;
offset += 6;
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, verts.size() * SB_VERTEX_SIZE, verts.data());
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_drawing = false;
}
}
void SpriteBatch::Render() {
glBindVertexArray(m_vao);
m_default->Bind();
m_default->SetMatrix4("projection", projection);
for (auto it = m_batches.begin(); it != m_batches.end(); ++it) {
RenderBatch* b = *it;
if (b->diffuse != nullptr) {
b->diffuse->Bind(0);
}
if (b->normal != nullptr) {
b->normal->Bind(1);
}
if (b->depth != nullptr) {
b->depth->Bind(2);
}
glDrawArrays(GL_TRIANGLES, b->offset, b->vertex_count);
glBindTexture(GL_TEXTURE_2D, 0);
}
m_default->Unbind();
glBindVertexArray(0);
}
void SpriteBatch::Draw(Vector2f position, Texture* diffuse) {
Sprite* spr = new Sprite();
spr->diffuse = diffuse;
spr->v1 = {
Vector3f(0, 0, 0),
Vector2f(0, 0),
Vector4f(1, 1, 1, 1)
};
spr->v2 = {
Vector3f(128, 0, 0),
Vector2f(1, 0),
Vector4f(1, 1, 1, 1)
};
spr->v3 = {
Vector3f(128, 128, 0),
Vector2f(1, 1),
Vector4f(1, 1, 1, 1)
};
spr->v4 = {
Vector3f(0, 128, 0),
Vector2f(0, 1),
Vector4f(1, 1, 1, 1)
};
m_sprites.push_back(spr);
}
SpriteBatch::~SpriteBatch() {
if (m_vbo) {
glDeleteBuffers(1, &m_vbo);
}
if (m_vao) {
glDeleteVertexArrays(1, &m_vao);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment