Sort entities by render type, bind buffers less often

This commit is contained in:
2025-06-03 22:03:11 +02:00
parent 9142531ece
commit 2996e8ecaf
7 changed files with 73 additions and 4 deletions
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include <stdbool.h>
/* There should also be an entity mesh type of QUAD1, as billboards
always face the camera, thus the back side need not be rendered. */
typedef struct Entity
{
enum { MESH_QUAD2, MESH_QUAD_X } mesh_type;
enum { ORIGIN_CENTER, ORIGIN_BOTTOM } origin;
enum { RENDER_NORMAL, RENDER_BILLBOARD_Y, RENDER_BILLBOARD } render_type;
void *userdata;
void (*on_tick) (struct Entity *self);
vec3 position;
float rotation;
vec3 scale; /* Unused for now. */
char *texture;
} Entity;
+1
View File
@@ -0,0 +1 @@
emssej@Komputer-Ze-Smieci.2233:1748755544
+8 -1
View File
@@ -5,11 +5,18 @@
/* There should also be an entity mesh type of QUAD1, as billboards
always face the camera, thus the back side need not be rendered. */
typedef enum EntityRenderType
{
RENDER_NORMAL,
RENDER_BILLBOARD,
RENDER_BILLBOARD_Y
} EntityRenderType;
typedef struct Entity
{
enum { MESH_QUAD2, MESH_QUAD_X } mesh_type;
enum { ORIGIN_CENTER, ORIGIN_BOTTOM } origin;
enum { RENDER_NORMAL, RENDER_BILLBOARD_Y, RENDER_BILLBOARD } render_type;
EntityRenderType render_type;
void *userdata;
+8 -1
View File
@@ -10,6 +10,8 @@ EntityMesh mesh_quad2, mesh_quad_x;
extern GameState game_state;
extern Resources resources;
unsigned int last_type = -1;
void
EntityManager_init ()
{
@@ -81,7 +83,6 @@ em_render_internal (gpointer data, gpointer userdata)
case RENDER_BILLBOARD_Y:
/* It's not quite a "real" billboard, but the effect is much
better on the eye. */
vec3 delta;
glm_vec3_sub (game_state.camera.position, entity->position, delta);
delta[1] = 0.0;
@@ -107,7 +108,13 @@ em_render_internal (gpointer data, gpointer userdata)
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, R_TEXGET (entity->texture));
if (entity->mesh_type != last_type)
{
EntityMesh_bind (&to_render);
}
last_type = entity->mesh_type;
EntityMesh_render (&to_render);
}
+28 -1
View File
@@ -9,7 +9,34 @@
#include "../resources.h"
#include "../state.h"
#define EM_ENTADD(entity) (g_sequence_append (entity_manager, entity));
#define EM_ENTADD(entity) (g_sequence_insert_sorted (entity_manager, entity, em_compare, NULL));
static inline int
em_compare (gconstpointer a, gconstpointer b, gpointer userdata)
/* This function is used to sort Entities by their mesh type, so that
diferrent buffers aren't bound every single frame. */
{
UNUSED (userdata);
const Entity *entity1 = a;
const Entity *entity2 = b;
if (entity1->mesh_type == entity2->mesh_type)
{
return 0;
}
if (entity1->mesh_type == MESH_QUAD_X && entity2->mesh_type == MESH_QUAD2)
{
return -1;
}
if (entity1->mesh_type == MESH_QUAD2 && entity2->mesh_type == MESH_QUAD_X)
{
return 1;
}
return (int) entity1->mesh_type - (int) entity2->mesh_type;
}
void EntityManager_init ();
void EntityManager_tick ();
+5 -1
View File
@@ -5,7 +5,7 @@
extern GameFlags game_flags;
void
EntityMesh_render (EntityMesh *mesh)
EntityMesh_bind (EntityMesh *mesh)
{
glBindBuffer (GL_ARRAY_BUFFER, mesh->pbo);
glEnableVertexAttribArray (0);
@@ -16,7 +16,11 @@ EntityMesh_render (EntityMesh *mesh)
glVertexAttribPointer (1, 2, GL_FLOAT, GL_FALSE, sizeof (float) * 2, 0);
glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, mesh->ebo);
}
void
EntityMesh_render (EntityMesh *mesh)
{
if (game_flags.wireframe_enabled)
{
glDrawElements (GL_LINES, mesh->indices_len, GL_UNSIGNED_INT, 0);
+1
View File
@@ -13,6 +13,7 @@ typedef struct EntityMesh
unsigned int ebo;
} EntityMesh;
void EntityMesh_bind (EntityMesh *mesh);
void EntityMesh_render (EntityMesh *mesh);
EntityMesh EntityMesh_make_quad2 ();
EntityMesh EntityMesh_make_quad_x ();