Skip to content

Commit

Permalink
Simplify custom item rendering by removing GL emissivity hacks
Browse files Browse the repository at this point in the history
  • Loading branch information
tterrag1098 committed Jan 10, 2019
1 parent 204ebdc commit da7c299
Showing 1 changed file with 20 additions and 71 deletions.
91 changes: 20 additions & 71 deletions src/main/java/net/minecraftforge/client/ForgeHooksClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -658,22 +658,16 @@ public static void renderLitItem(RenderItem ri, IBakedModel model, int color, It
List<BakedQuad> segment = new ArrayList<>();

// Lighting of the current segment
int segmentBlockLight = -1;
int segmentSkyLight = -1;
// Coloring of the current segment
int segmentColorMultiplier = color;
int segmentBlockLight = 0;
int segmentSkyLight = 0;
// Diffuse lighting state
boolean segmentShading = true;
// State changed by the current segment
boolean segmentLightingDirty = false;
boolean segmentColorDirty = false;
boolean segmentShadingDirty = false;
// If the current segment contains lighting data
boolean hasLighting = false;

// Tint index cache to avoid unnecessary IItemColor lookups
int prevTintIndex = -1;

for (int i = 0; i < allquads.size(); i++)
{
BakedQuad q = allquads.get(i);
Expand All @@ -693,94 +687,66 @@ public static void renderLitItem(RenderItem ri, IBakedModel model, int color, It
}
}

int colorMultiplier = segmentColorMultiplier;

// If there is no color override, and this quad is tinted, we need to apply IItemColor
if (color == 0xFFFFFFFF && q.hasTintIndex())
{
int tintIndex = q.getTintIndex();

if (prevTintIndex != tintIndex)
{
colorMultiplier = getColorMultiplier(stack, tintIndex);
}
prevTintIndex = tintIndex;
}
else
{
colorMultiplier = color;
prevTintIndex = -1;
}

boolean shade = q.shouldApplyDiffuseLighting();

boolean lightingDirty = segmentBlockLight != bl || segmentSkyLight != sl;
boolean colorDirty = hasLighting && segmentColorMultiplier != colorMultiplier;
boolean shadeDirty = shade != segmentShading;

// If lighting or color data has changed, draw the segment and flush it
if (lightingDirty || colorDirty || shadeDirty)
if (lightingDirty || shadeDirty)
{
if (i > 0) // Make sure this isn't the first quad being processed
{
drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentColorMultiplier, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < i), segmentColorDirty, segmentShadingDirty);
drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < i), segmentShadingDirty);
}
segmentBlockLight = bl;
segmentSkyLight = sl;
segmentColorMultiplier = colorMultiplier;
segmentShading = shade;
segmentLightingDirty = lightingDirty;
segmentColorDirty = colorDirty;
segmentShadingDirty = shadeDirty;
hasLighting = segmentBlockLight > 0 || segmentSkyLight > 0;
hasLighting = segmentBlockLight > 0 || segmentSkyLight > 0 || !segmentShading;
}

segment.add(q);
}

drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentColorMultiplier, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < allquads.size()), segmentColorDirty, segmentShadingDirty);
drawSegment(ri, color, stack, segment, segmentBlockLight, segmentSkyLight, segmentShading, segmentLightingDirty && (hasLighting || segment.size() < allquads.size()), segmentShadingDirty);

// Clean up render state if necessary
if (hasLighting)
{
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, OpenGlHelper.lastBrightnessX, OpenGlHelper.lastBrightnessY);
GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0, 0, 0, 1));
GlStateManager.enableLighting();
}
}

private static void drawSegment(RenderItem ri, int baseColor, ItemStack stack, List<BakedQuad> segment, int bl, int sl, int tintColor, boolean shade, boolean updateLighting, boolean updateColor, boolean updateShading)
private static void drawSegment(RenderItem ri, int baseColor, ItemStack stack, List<BakedQuad> segment, int bl, int sl, boolean shade, boolean updateLighting, boolean updateShading)
{
BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM);

float lastBl = OpenGlHelper.lastBrightnessX;
float lastSl = OpenGlHelper.lastBrightnessY;

if (updateLighting || updateColor || updateShading)
if (updateShading)
{
if (!shade)
if (shade)
{
// When diffuse lighting is off, set the emissive buffer to "disable" the GL lighting effects and emulate the block rendering
float emissive = Math.max(bl, sl) / 240f;

float r = (tintColor >>> 16 & 0xff) / 255f;
float g = (tintColor >>> 8 & 0xff) / 255f;
float b = (tintColor & 0xff) / 255f;

GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(emissive * r, emissive * g, emissive * b, 1));
// (Re-)enable lighting for normal look with shading
GlStateManager.enableLighting();
}
else
{
// Otherwise leave it as-is (or reset it) so that normal lighting effects take hold
// Color will be set instead by downstream RenderItem#renderQuads
GL11.glMaterial(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0, 0, 0, 1));
}

if (updateLighting)
{
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, Math.max(bl, lastBl), Math.max(sl, lastSl));
// Disable lighting to simulate a lack of diffuse lighting
GlStateManager.disableLighting();
}
}

if (updateLighting)
{
// Force lightmap coords to simulate synthetic lighting
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, Math.max(bl, lastBl), Math.max(sl, lastSl));
}

ri.renderQuads(bufferbuilder, segment, baseColor, stack);
Tessellator.getInstance().draw();
Expand All @@ -791,23 +757,6 @@ private static void drawSegment(RenderItem ri, int baseColor, ItemStack stack, L

segment.clear();
}

private static int getColorMultiplier(ItemStack stack, int tintIndex)
{
if (tintIndex == -1 || stack.isEmpty()) return 0xFFFFFFFF;

int colorMultiplier = Minecraft.getMinecraft().getItemColors().colorMultiplier(stack, tintIndex);

if (EntityRenderer.anaglyphEnable)
{
colorMultiplier = TextureUtil.anaglyphColor(colorMultiplier);
}

// Always full opacity
colorMultiplier |= 0xff << 24; // -16777216

return colorMultiplier;
}

/**
* internal, relies on fixed format of FaceBakery
Expand Down

0 comments on commit da7c299

Please sign in to comment.