Skip to main content
The entity rendering system handles all moving objects in the game, including mobs, players, projectiles, and items, using a flexible model-based architecture.

Architecture

Base Class Hierarchy

EntityRenderer (abstract base)
  ├─ MobRenderer (for living entities)
  │   ├─ HumanoidMobRenderer
  │   │   ├─ PlayerRenderer
  │   │   ├─ ZombieRenderer
  │   │   ├─ SkeletonRenderer
  │   │   └─ ...
  │   ├─ QuadrupedRenderer
  │   │   ├─ PigRenderer
  │   │   ├─ CowRenderer
  │   │   ├─ SheepRenderer
  │   │   └─ ...
  │   └─ Other specialized renderers
  │       ├─ SpiderRenderer
  │       ├─ EndermanRenderer
  │       ├─ GhastRenderer
  │       └─ ...
  └─ Simple entity renderers
      ├─ BoatRenderer
      ├─ MinecartRenderer
      ├─ ArrowRenderer
      ├─ ItemRenderer
      └─ ...

EntityRenderer Base Class

class EntityRenderer {
public:
    virtual void render(shared_ptr<Entity> entity, double x, double y, double z, 
                       float rot, float a) = 0;
protected:
    float shadowRadius;
    float shadowStrength;
    Model *model;
    TileRenderer *tileRenderer;
};
See: EntityRenderer.h:20

Core Methods

Render Method

virtual void render(shared_ptr<Entity> entity, double x, double y, double z,
                   float rot, float a) = 0;
Parameters:
  • entity - The entity to render
  • x, y, z - Interpolated position
  • rot - Body rotation
  • a - Frame interpolation alpha (0.0 to 1.0)
See: EntityRenderer.h:39

Texture Binding

virtual void bindTexture(int resourceName);
virtual void bindTexture(const wstring& resourceName);
virtual bool bindTexture(const wstring& urlTexture, int backupTexture);
See: EntityRenderer.h:41-45

Shadow Rendering

virtual void renderShadow(shared_ptr<Entity> e, double x, double y, double z,
                         float pow, float a);
See: EntityRenderer.h:48

Post-Render

virtual void postRender(shared_ptr<Entity> entity, double x, double y, double z,
                       float rot, float a, bool bRenderPlayerShadow);
Handles name tags and additional post-rendering effects. See: EntityRenderer.h:57

MobRenderer

class MobRenderer : public EntityRenderer {
protected:
    Model *model;
    Model *armor;
public:
    MobRenderer(Model *model, float shadow);
};
See: MobRenderer.h:11

Render Pipeline

The MobRenderer::render method follows this sequence:
  1. Setup Position - setupPosition()
  2. Setup Rotations - setupRotations()
  3. Render Model - renderModel()
  4. Render Armor - Multiple passes for armor layers
  5. Additional Rendering - additionalRendering()
  6. Name Tag - renderName()
See: MobRenderer.h:26

Model Rendering

virtual void renderModel(shared_ptr<Entity> mob, float wp, float ws, float bob,
                        float headRotMinusBodyRot, float headRotx, float scale);
Parameters:
  • wp - Walk position
  • ws - Walk speed
  • bob - Bobbing amount
  • headRotMinusBodyRot - Head rotation relative to body
  • headRotx - Head pitch rotation
  • scale - Model scale
See: MobRenderer.h:28

Rotation Setup

virtual void setupRotations(shared_ptr<Mob> mob, float bob, 
                           float bodyRot, float a);
Handles:
  • Death animation rotation
  • Body rotation
  • Bobbing animation
  • Flip degrees when dying
See: MobRenderer.h:30

Armor Rendering

Armor is rendered in multiple layers:
static const int MAX_ARMOR_LAYERS = 4;

virtual int prepareArmorOverlay(shared_ptr<Mob> mob, int layer, float a);
virtual int prepareArmor(shared_ptr<Mob> mob, int layer, float a);
virtual void prepareSecondPassArmor(shared_ptr<Mob> mob, int layer, float a);
See: MobRenderer.h:14 and MobRenderer.h:34-36

Name Tag Rendering

virtual void renderNameTag(shared_ptr<Mob> mob, const wstring& name,
                          double x, double y, double z, int maxDist, 
                          int color = 0xff000000);
See: MobRenderer.h:41 Name tags are visible within specific distances:
#define PLAYER_NAME_READABLE_FULLSCREEN 16
#define PLAYER_NAME_READABLE_DISTANCE_SPLITSCREEN 8
#define PLAYER_NAME_READABLE_DISTANCE_SD 8
See: MobRenderer.h:6-8

Model System

Base Model Class

class Model {
public:
    float attackTime;
    bool riding;
    vector<ModelPart *> cubes;
    bool young;
    
    virtual void render(shared_ptr<Entity> entity, float time, float r, float bob,
                       float yRot, float xRot, float scale, bool usecompiled);
    virtual void setupAnim(float time, float r, float bob, float yRot, 
                          float xRot, float scale, unsigned int uiBitmaskOverrideAnim=0);
    virtual void prepareMobModel(shared_ptr<Mob> mob, float time, float r, float a);
};
See: Model.h:10

Model Parts

Models are composed of ModelPart objects representing body parts:
vector<ModelPart *> cubes;
Each part can have:
  • Position and rotation
  • Child parts
  • Texture coordinates
  • Compiled display lists

Texture Mapping

unordered_map<wstring, TexOffs *> mappedTexOffs;
int texWidth;
int texHeight;

void setMapTex(wstring id, int x, int y);
TexOffs *getMapTex(wstring id);
See: Model.h:17-29

HumanoidModel

class HumanoidModel : public Model {
public:
    ModelPart *head, *hair, *body, *arm0, *arm1, *leg0, *leg1, *ear, *cloak;
    
    int holdingLeftHand;
    int holdingRightHand;
    bool idle;
    bool sneaking;
    bool bowAndArrow;
    bool eating;
};
See: HumanoidModel.h:4

Animation System

HumanoidModel supports various animation overrides:
enum animbits {
    eAnim_ArmsDown = 0,
    eAnim_ArmsOutFront,
    eAnim_NoLegAnim,
    eAnim_HasIdle,
    eAnim_ForceAnim,
    eAnim_SingleLegs,      // Both legs move together
    eAnim_SingleArms,      // Both arms move together
    eAnim_StatueOfLiberty, // Weeping Angel style
    eAnim_DontRenderArmour,
    eAnim_NoBobbing,
    eAnim_DisableRenderHead,
    eAnim_DisableRenderArm0,
    eAnim_DisableRenderArm1,
    eAnim_DisableRenderTorso,
    eAnim_DisableRenderLeg0,
    eAnim_DisableRenderLeg1,
    eAnim_DisableRenderHair
};
See: HumanoidModel.h:20-40

Setup Animation

virtual void setupAnim(float time, float r, float bob, float yRot,
                      float xRot, float scale, 
                      unsigned int uiBitmaskOverrideAnim=0);
Calculates limb rotations based on:
  • Walking animation
  • Idle animation
  • Sneaking pose
  • Bow drawing
  • Eating
  • Riding
  • Swimming
  • Custom skin animations
See: HumanoidModel.h:58

Rendering Components

void renderHair(float scale, bool usecompiled);
void renderEars(float scale, bool usecompiled);
void renderCloak(float scale, bool usecompiled);
See: HumanoidModel.h:59-61

Specialized Models

BookModel

class BookModel : public Model {
public:
    ModelPart *leftLid, *rightLid;
    ModelPart *leftPages, *rightPages;
    ModelPart *flipPage1, *flipPage2;
    ModelPart *seam;
};
See: BookModel.h:5 Used for enchantment tables and books.

QuadrupedModel

For animals with four legs:
  • PigModel
  • CowModel
  • SheepModel
  • WolfModel
  • OzelotModel

Specialized Mob Models

  • SpiderModel - 8 legs with articulation
  • GhastModel - Floating body with tentacles
  • SlimeModel - Scalable cube
  • EnderDragonModel - Complex multi-part dragon
  • SquidModel - Body with 8 tentacles

Example Renderers

BlazeRenderer

class BlazeRenderer : public MobRenderer {
private:
    int modelVersion;
public:
    virtual void render(shared_ptr<Entity> mob, double x, double y, double z,
                       float rot, float a);
};
See: BlazeRenderer.h:5

BoatRenderer

class BoatRenderer : public EntityRenderer {
protected:
    Model *model;
public:
    virtual void render(shared_ptr<Entity> boat, double x, double y, double z,
                       float rot, float a);
};
See: BoatRenderer.h:4 Renders boats with:
  • Water bobbing animation
  • Paddle animation
  • Damage texture overlay

EntityRenderDispatcher

Central registry for all entity renderers:
class EntityRenderDispatcher {
public:
    static EntityRenderDispatcher *instance;
    
    void prepare(Level *level, Textures *textures, Font *font,
                shared_ptr<Entity> player, Options *options, float a);
    void render(shared_ptr<Entity> entity, float a);
    
    static double xOff, yOff, zOff;  // Camera offset
};
Maintains a map of entity types to renderers.

TileEntityRenderDispatcher

Similar system for tile entities:
class TileEntityRenderDispatcher {
public:
    static TileEntityRenderDispatcher *instance;
    
    void prepare(Level *level, Textures *textures, Font *font,
                shared_ptr<Entity> player, float a);
    void render(shared_ptr<TileEntity> tileEntity, float a);
    
    static double xOff, yOff, zOff;
};

Custom Skin Support

The system supports custom player skins:
  • 64×64 texture support (via _reinit)
  • HD skin textures
  • Animated skin features
  • Custom model parts
void _reinit(int newTexWidth, int newTexHeight);
See: HumanoidModel.h:53

Performance Considerations

Compiled Models

Models can use OpenGL display lists:
virtual void render(shared_ptr<Entity> entity, float time, float r, float bob,
                   float yRot, float xRot, float scale, 
                   bool usecompiled);  // Use compiled display lists

Shadow Rendering

Shadows are rendered as:
  • Projected texture on ground
  • Strength fades with height
  • Radius based on entity size
  • Optional tile-based shadow occlusion

Flame Rendering

Entities on fire have flames rendered:
virtual void renderFlame(shared_ptr<Entity> e, double x, double y, double z, float a);
See: EntityRenderer.h:47

Integration with Rendering Pipeline

Entity rendering is called from LevelRenderer::renderEntities:
  1. Prepare dispatchers with camera offset
  2. Enable lighting layer
  3. Render global entities (no culling)
  4. Render regular entities (with frustum culling)
  5. Render tile entities
  6. Disable lighting layer
See: LevelRenderer.cpp:494-604

Build docs developers (and LLMs) love