Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Small!
- struct ModelEntityDepthPtr {
- // Does this really need to be double?
- double depth;
- U32 index;
- };
- internal inline
- int entity_depth_cmp(const void *e1, const void *e2)
- {
- // Smallest Z first (furthest away from camera)
- // Uglier but faster than using temp vars with -O0
- return ( ((ModelEntityDepthPtr*)e1)->depth > ((ModelEntityDepthPtr*)e2)->depth ) -
- ( ((ModelEntityDepthPtr*)e1)->depth < ((ModelEntityDepthPtr*)e2)->depth );
- }
- void render_frame()
- {
- // Cache!
- Renderer *r= g_env.renderer;
- ModelEntity *entities= r->entities;
- // Eww, global maybe stick to renderer, but don't allocate a new one every frame
- static ModelEntityDepthPtr sorted_entities[MAX_MODELENTITY_COUNT];
- U32 num_visible_entities= 0;
- // This part still trashes the cache
- for (U32 i = 0; i < MAX_MODELENTITY_COUNT; i++)
- {
- ModelEntity *e= entities[i];
- // Maybe store these in separate bit-array for performance if this becomes slow
- // if (r->entity_has_model[i / 32] & (1 << i % 32)) // Complexity! Would relieve cache pressure ~500x if lots of empty entities though
- if (!e->model_name[0])
- continue;
- // Do some super cheap cull test here (can be skipped in the beginning and this will still probably be faster, less copying)
- if (is_visible(e, camera))
- {
- // Store only the depth and index so they are cheaper to shuffle around when sorting
- sorted_entities[num_visible_entities]= (ModelEntityDepthPtr) { .depth = e->pos.z, .index = i };
- ++num_visible_entities;
- }
- }
- // Z-sort
- qsort(sorted_entities, num_visible_entities, sizeof(*sorted_entities), entity_depth_cmp);
- // Generate the geometry here
- for (U32 i = 0; i < num_visible_entities; i++)
- {
- // This looks bad but entities array is already in cache
- ModelEntity *e= entities[sorted_entities[i].index];
- // Draw!
- }
- // Actually render!
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement