You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.0 KiB
135 lines
4.0 KiB
#include "sprite.h"
|
|
#include "texture.h"
|
|
#include "shader.h"
|
|
#include "renderer.h"
|
|
#include "../common/log.h"
|
|
#include "../common/array.h"
|
|
#include "gl_load.h"
|
|
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
void sprite_batch_create(struct Sprite_Batch* batch, const char* texture_name, const char* vert_shader, const char* frag_shader, int draw_mode)
|
|
{
|
|
assert(batch);
|
|
memset(&batch->sprites[0], 0, sizeof(struct Sprite) * SPRITE_BATCH_SIZE);
|
|
glGenVertexArrays(1, &batch->vao);
|
|
|
|
glBindVertexArray(batch->vao);
|
|
|
|
glGenBuffers(1, &batch->vbo);
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo);
|
|
GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
|
|
sizeof(struct Sprite_Vertex) * MAX_SPRITE_VERTICES * SPRITE_BATCH_SIZE,
|
|
NULL,
|
|
GL_STREAM_DRAW));
|
|
|
|
// Position
|
|
GL_CHECK(glVertexAttribPointer(ATTRIB_LOC_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(struct Sprite_Vertex), 0));
|
|
GL_CHECK(glEnableVertexAttribArray(ATTRIB_LOC_POSITION));
|
|
|
|
// Uvs
|
|
GL_CHECK(glVertexAttribPointer(ATRRIB_LOC_UV, 2, GL_FLOAT, GL_FALSE, sizeof(struct Sprite_Vertex), sizeof(vec2)));
|
|
GL_CHECK(glEnableVertexAttribArray(ATRRIB_LOC_UV));
|
|
|
|
// Color
|
|
GL_CHECK(glVertexAttribPointer(ATTRIB_LOC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(struct Sprite_Vertex), sizeof(vec2) + sizeof(vec2)));
|
|
GL_CHECK(glEnableVertexAttribArray(ATTRIB_LOC_COLOR));
|
|
|
|
//glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
glBindVertexArray(0);
|
|
|
|
int texture = texture_create_from_file(texture_name, TU_DIFFUSE);
|
|
if(texture < 0)
|
|
{
|
|
log_error("sprite_batch:create", "Failed to find texture '%s' when creating sprite batch", texture_name);
|
|
texture = texture_create_from_file("default.tga", TU_DIFFUSE);
|
|
}
|
|
batch->texture = texture;
|
|
|
|
int shader = shader_create(vert_shader, frag_shader);
|
|
if(shader < -1)
|
|
{
|
|
log_error("sprite_batch:create", "Failed to create shader from '%s'/'%s' sprite batch", vert_shader, frag_shader);
|
|
shader = shader_create("default.vert", "default.frag");
|
|
}
|
|
batch->shader = shader;
|
|
batch->draw_mode = draw_mode;
|
|
batch->current_sprite_count = 0;
|
|
}
|
|
|
|
void sprite_batch_remove(struct Sprite_Batch * batch)
|
|
{
|
|
assert(batch);
|
|
glDeleteBuffers(1, &batch->vbo);
|
|
glDeleteVertexArrays(1, &batch->vbo);
|
|
batch->current_sprite_count = 0;
|
|
texture_remove(batch->texture);
|
|
shader_remove(batch->shader);
|
|
|
|
batch->texture = -1;
|
|
batch->shader = -1;
|
|
batch->current_sprite_count = 0;
|
|
batch->vao = 0;
|
|
batch->vbo = 0;
|
|
memset(&batch->sprites[0], 0, sizeof(struct Sprite) * SPRITE_BATCH_SIZE);
|
|
}
|
|
|
|
void sprite_batch_begin(struct Sprite_Batch* batch)
|
|
{
|
|
assert(batch);
|
|
batch->current_sprite_count = 0;
|
|
}
|
|
|
|
void sprite_batch_add_sprite(struct Sprite_Batch* batch, struct Sprite* sprite)
|
|
{
|
|
assert(batch);
|
|
if(batch->current_sprite_count < SPRITE_BATCH_SIZE)
|
|
{
|
|
batch->current_sprite_count++;
|
|
memcpy(&batch->sprites[batch->current_sprite_count - 1], sprite, sizeof(struct Sprite));
|
|
}
|
|
else
|
|
{
|
|
log_error("sprite_batch:add_sprite", "Batch full");
|
|
}
|
|
}
|
|
|
|
void sprite_batch_add_sprite_new(struct Sprite_Batch* batch, int texture, struct Sprite_Vertex vertices[MAX_SPRITE_VERTICES])
|
|
{
|
|
assert(batch);
|
|
if(batch->current_sprite_count < SPRITE_BATCH_SIZE)
|
|
{
|
|
batch->current_sprite_count++;
|
|
memcpy(&batch->sprites[batch->current_sprite_count - 1], &vertices[0], sizeof(struct Sprite));
|
|
}
|
|
else
|
|
{
|
|
log_error("sprite_batch:add_sprite", "Batch full");
|
|
}
|
|
}
|
|
|
|
void sprite_batch_end(struct Sprite_Batch* batch)
|
|
{
|
|
assert(batch);
|
|
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo);
|
|
GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER,
|
|
0,
|
|
sizeof(struct Sprite_Vertex) * MAX_SPRITE_VERTICES * batch->current_sprite_count,
|
|
&batch->sprites[0]));
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
}
|
|
|
|
void sprite_batch_render(struct Sprite_Batch* batch)
|
|
{
|
|
assert(batch);
|
|
if(batch->current_sprite_count == 0) return;
|
|
|
|
texture_bind(batch->texture);
|
|
glBindVertexArray(batch->vao);
|
|
|
|
GL_CHECK(glDrawArrays(batch->draw_mode, 0, MAX_SPRITE_VERTICES * batch->current_sprite_count));
|
|
|
|
glBindVertexArray(0);
|
|
texture_unbind(batch->texture);
|
|
}
|
|
|