ref: eb6ab89b85684308f2e5c41c0ca70fbdb52a9bdb
parent: 1b2d4fdb4d2dd0b659df9aab59481022dc4f2ae1
author: Clownacy <[email protected]>
date: Sat Feb 1 19:01:45 EST 2020
Fixes and improvements Made texture-atlasing occur immediately, notably.
--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -50,6 +50,7 @@
unsigned char *pixels;
unsigned int width;
unsigned int height;
+ unsigned int pitch;
} Backend_Glyph;
typedef struct Coordinate2D
@@ -306,19 +307,21 @@
return program_id;
}
-static VertexBufferSlot* GetVertexBufferSlot(void)
+static VertexBufferSlot* GetVertexBufferSlot(unsigned int slots_needed)
{
- if (current_vertex_buffer_slot >= local_vertex_buffer_size)
+ if (current_vertex_buffer_slot + slots_needed > local_vertex_buffer_size)
{
- if (local_vertex_buffer_size == 0)
- local_vertex_buffer_size = 1;
- else
+ local_vertex_buffer_size = 1;
+
+ while (current_vertex_buffer_slot + slots_needed > local_vertex_buffer_size)
local_vertex_buffer_size <<= 1;
local_vertex_buffer = (VertexBufferSlot*)realloc(local_vertex_buffer, local_vertex_buffer_size * sizeof(VertexBufferSlot));
}
- return &local_vertex_buffer[current_vertex_buffer_slot++];
+ current_vertex_buffer_slot += slots_needed;
+
+ return &local_vertex_buffer[current_vertex_buffer_slot - slots_needed];
}
static void FlushVertexBuffer(void)
@@ -352,7 +355,7 @@
}
// Blit the glyphs in the batch
-static void GlyphBatch_Draw(spritebatch_sprite_t* sprites, int count, int texture_w, int texture_h, void* udata)
+static void GlyphBatch_Draw(spritebatch_sprite_t *sprites, int count, int texture_w, int texture_h, void *udata)
{
static Backend_Surface *last_surface;
static GLuint last_texture_id;
@@ -393,12 +396,15 @@
glBindTexture(GL_TEXTURE_2D, texture_id);
}
+ VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot(count);
+ printf("%d\n", count);
+
for (int i = 0; i < count; ++i)
{
Backend_Glyph *glyph = (Backend_Glyph*)sprites[i].image_id;
const GLfloat texture_left = sprites[i].minx;
- const GLfloat texture_right = sprites[i].maxx;
+ const GLfloat texture_right = texture_left + ((GLfloat)glyph->width / (GLfloat)texture_w); // Account for pitch
const GLfloat texture_top = sprites[i].maxy;
const GLfloat texture_bottom = sprites[i].miny;
@@ -407,8 +413,6 @@
const GLfloat vertex_top = (sprites[i].y * (2.0f / glyph_destination_surface->height)) - 1.0f;
const GLfloat vertex_bottom = ((sprites[i].y + glyph->height) * (2.0f / glyph_destination_surface->height)) - 1.0f;
- VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
-
vertex_buffer_slot->vertices[0][0].texture_coordinate.x = texture_left;
vertex_buffer_slot->vertices[0][0].texture_coordinate.y = texture_top;
vertex_buffer_slot->vertices[0][1].texture_coordinate.x = texture_right;
@@ -436,6 +440,8 @@
vertex_buffer_slot->vertices[1][1].vertex_coordinate.y = vertex_bottom;
vertex_buffer_slot->vertices[1][2].vertex_coordinate.x = vertex_left;
vertex_buffer_slot->vertices[1][2].vertex_coordinate.y = vertex_bottom;
+
+ ++vertex_buffer_slot;
}
}
@@ -450,10 +456,13 @@
}
// Create a texture atlas, and upload pixels to it
-static SPRITEBATCH_U64 GlyphBatch_CreateTexture(void* pixels, int w, int h, void* udata)
+static SPRITEBATCH_U64 GlyphBatch_CreateTexture(void *pixels, int w, int h, void *udata)
{
(void)udata;
+// printf("%d\n", w);
+// printf("%d\n\n", h);
+
GLint previously_bound_texture;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &previously_bound_texture);
@@ -480,7 +489,7 @@
}
// Destroy texture atlas
-static void GlyphBatch_DestroyTexture(SPRITEBATCH_U64 texture_id, void* udata)
+static void GlyphBatch_DestroyTexture(SPRITEBATCH_U64 texture_id, void *udata)
{
(void)udata;
@@ -601,6 +610,9 @@
// Set-up glyph-batcher
spritebatch_config_t config;
spritebatch_set_default_config(&config);
+ config.pixel_stride = 1;
+ config.lonely_buffer_count_till_flush = 0; // Start making atlases immediately
+ config.ticks_to_decay_texture = 100; // If a glyph hasn't been used for the past 100 draws, destroy it
config.batch_callback = GlyphBatch_Draw;
config.get_pixels_callback = GlyphBatch_GetPixels;
config.generate_texture_callback = GlyphBatch_CreateTexture;
@@ -701,7 +713,7 @@
// Draw framebuffer to screen
glBindTexture(GL_TEXTURE_2D, framebuffer.texture_id);
- VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
+ VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot(1);
vertex_buffer_slot->vertices[0][0].texture_coordinate.x = 0.0f;
vertex_buffer_slot->vertices[0][0].texture_coordinate.y = 1.0f;
@@ -868,7 +880,7 @@
const GLfloat vertex_top = (y * (2.0f / destination_surface->height)) - 1.0f;
const GLfloat vertex_bottom = ((y + (rect->bottom - rect->top)) * (2.0f / destination_surface->height)) - 1.0f;
- VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
+ VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot(1);
vertex_buffer_slot->vertices[0][0].texture_coordinate.x = texture_left;
vertex_buffer_slot->vertices[0][0].texture_coordinate.y = texture_top;
@@ -941,7 +953,7 @@
const GLfloat vertex_top = (rect->top * (2.0f / surface->height)) - 1.0f;
const GLfloat vertex_bottom = (rect->bottom * (2.0f / surface->height)) - 1.0f;
- VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot();
+ VertexBufferSlot *vertex_buffer_slot = GetVertexBufferSlot(1);
vertex_buffer_slot->vertices[0][0].vertex_coordinate.x = vertex_left;
vertex_buffer_slot->vertices[0][0].vertex_coordinate.y = vertex_top;
@@ -964,9 +976,9 @@
if (glyph != NULL)
{
- const unsigned int destination_pitch = (width + 3) & ~3; // Round up to the nearest 4 (OpenGL needs this)
+ glyph->pitch = (width + 3) & ~3; // Round up to the nearest 4 (OpenGL needs this)
- glyph->pixels = (unsigned char*)malloc(destination_pitch * height);
+ glyph->pixels = (unsigned char*)malloc(glyph->pitch * height);
if (glyph->pixels != NULL)
{
@@ -973,7 +985,7 @@
for (unsigned int y = 0; y < height; ++y)
{
const unsigned char *source_pointer = &pixels[y * pitch];
- unsigned char *destination_pointer = &glyph->pixels[y * destination_pitch];
+ unsigned char *destination_pointer = &glyph->pixels[y * glyph->pitch];
memcpy(destination_pointer, source_pointer, width);
}
@@ -1007,7 +1019,7 @@
void Backend_DrawGlyph(Backend_Glyph *glyph, long x, long y)
{
- spritebatch_push(&glyph_batcher, (SPRITEBATCH_U64)glyph, glyph->width, glyph->height, x, y, 1.0f, 1.0f, 0.0f, 0.0f, 0);
+ spritebatch_push(&glyph_batcher, (SPRITEBATCH_U64)glyph, glyph->pitch, glyph->height, x, y, 1.0f, 1.0f, 0.0f, 0.0f, 0);
}
void Backend_FlushGlyphs(void)
--- a/src/Backends/Rendering/SDLTexture.cpp
+++ b/src/Backends/Rendering/SDLTexture.cpp
@@ -80,9 +80,10 @@
{
Backend_Glyph *glyph = (Backend_Glyph*)sprites[i].image_id;
+ SDL_Rect source_rect = {(int)(texture_w * sprites[i].minx), (int)(texture_h * sprites[i].maxy), glyph->width, glyph->height};
SDL_Rect destination_rect = {(int)sprites[i].x, (int)sprites[i].y, glyph->width, glyph->height};
- SDL_RenderCopy(renderer, texture_atlas, NULL, &destination_rect);
+ SDL_RenderCopy(renderer, texture_atlas, &source_rect, &destination_rect);
}
}
@@ -171,6 +172,9 @@
// Set-up glyph-batcher
spritebatch_config_t config;
spritebatch_set_default_config(&config);
+ config.pixel_stride = 4;
+ config.lonely_buffer_count_till_flush = 0; // Start making atlases immediately
+ config.ticks_to_decay_texture = 100; // If a glyph hasn't been used for the past 100 draws, destroy it
config.batch_callback = GlyphBatch_Draw;
config.get_pixels_callback = GlyphBatch_GetPixels;
config.generate_texture_callback = GlyphBatch_CreateTexture;