Sort entities by render type, bind buffers less often
This commit is contained in:
@@ -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;
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
emssej@Komputer-Ze-Smieci.2233:1748755544
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
Reference in New Issue
Block a user