Simplify custom item rendering by removing GL emissivity hacks

This commit is contained in:
tterrag 2019-01-07 18:19:53 -05:00
parent d02da21a7a
commit e70cc4fcae
1 changed files with 21 additions and 67 deletions

View File

@ -625,22 +625,16 @@ public class ForgeHooksClient
List<BakedQuad> segment = new ArrayList<>(); List<BakedQuad> segment = new ArrayList<>();
// Lighting of the current segment // Lighting of the current segment
int segmentBlockLight = -1; int segmentBlockLight = 0;
int segmentSkyLight = -1; int segmentSkyLight = 0;
// Coloring of the current segment
int segmentColorMultiplier = color;
// Diffuse lighting state // Diffuse lighting state
boolean segmentShading = true; boolean segmentShading = true;
// State changed by the current segment // State changed by the current segment
boolean segmentLightingDirty = false; boolean segmentLightingDirty = false;
boolean segmentColorDirty = false;
boolean segmentShadingDirty = false; boolean segmentShadingDirty = false;
// If the current segment contains lighting data // If the current segment contains lighting data
boolean hasLighting = false; boolean hasLighting = false;
// Tint index cache to avoid unnecessary IItemColor lookups
int prevTintIndex = -1;
for (int i = 0; i < allquads.size(); i++) for (int i = 0; i < allquads.size(); i++)
{ {
BakedQuad q = allquads.get(i); BakedQuad q = allquads.get(i);
@ -660,62 +654,40 @@ public class ForgeHooksClient
} }
} }
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 shade = q.shouldApplyDiffuseLighting();
boolean lightingDirty = segmentBlockLight != bl || segmentSkyLight != sl; boolean lightingDirty = segmentBlockLight != bl || segmentSkyLight != sl;
boolean colorDirty = hasLighting && segmentColorMultiplier != colorMultiplier;
boolean shadeDirty = shade != segmentShading; boolean shadeDirty = shade != segmentShading;
// If lighting or color data has changed, draw the segment and flush it // 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 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; segmentBlockLight = bl;
segmentSkyLight = sl; segmentSkyLight = sl;
segmentColorMultiplier = colorMultiplier;
segmentShading = shade; segmentShading = shade;
segmentLightingDirty = lightingDirty; segmentLightingDirty = lightingDirty;
segmentColorDirty = colorDirty;
segmentShadingDirty = shadeDirty; segmentShadingDirty = shadeDirty;
hasLighting = segmentBlockLight > 0 || segmentSkyLight > 0; hasLighting = segmentBlockLight > 0 || segmentSkyLight > 0 || !segmentShading;
} }
segment.add(q); 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 // Clean up render state if necessary
if (hasLighting) if (hasLighting)
{ {
OpenGlHelper.glMultiTexCoord2f(OpenGlHelper.GL_TEXTURE1, OpenGlHelper.lastBrightnessX, OpenGlHelper.lastBrightnessY); OpenGlHelper.glMultiTexCoord2f(OpenGlHelper.GL_TEXTURE0, OpenGlHelper.lastBrightnessX, OpenGlHelper.lastBrightnessY);
GL11.glMaterialfv(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0, 0, 0, 1)); GlStateManager.enableLighting();
} }
} }
private static void drawSegment(ItemRenderer 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(ItemRenderer ri, int baseColor, ItemStack stack, List<BakedQuad> segment, int bl, int sl, boolean shade, boolean updateLighting, boolean updateShading)
{ {
BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer(); BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM); bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.ITEM);
@ -723,31 +695,25 @@ public class ForgeHooksClient
float lastBl = OpenGlHelper.lastBrightnessX; float lastBl = OpenGlHelper.lastBrightnessX;
float lastSl = OpenGlHelper.lastBrightnessY; 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 // (Re-)enable lighting for normal look with shading
float emissive = Math.max(bl, sl) / 240f; GlStateManager.enableLighting();
float r = (tintColor >>> 16 & 0xff) / 255f;
float g = (tintColor >>> 8 & 0xff) / 255f;
float b = (tintColor & 0xff) / 255f;
GL11.glMaterialfv(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(emissive * r, emissive * g, emissive * b, 1));
} }
else else
{ {
// Otherwise leave it as-is (or reset it) so that normal lighting effects take hold // Disable lighting to simulate a lack of diffuse lighting
// Color will be set instead by downstream RenderItem#renderQuads GlStateManager.disableLighting();
GL11.glMaterialfv(GL11.GL_FRONT_AND_BACK, GL11.GL_EMISSION, RenderHelper.setColorBuffer(0, 0, 0, 1));
}
if (updateLighting)
{
OpenGlHelper.glMultiTexCoord2f(OpenGlHelper.GL_TEXTURE1, Math.max(bl, lastBl), Math.max(sl, lastSl));
} }
} }
if (updateLighting)
{
// Force lightmap coords to simulate synthetic lighting
OpenGlHelper.glMultiTexCoord2f(OpenGlHelper.GL_TEXTURE0, Math.max(bl, lastBl), Math.max(sl, lastSl));
}
ri.renderQuads(bufferbuilder, segment, baseColor, stack); ri.renderQuads(bufferbuilder, segment, baseColor, stack);
Tessellator.getInstance().draw(); Tessellator.getInstance().draw();
@ -759,18 +725,6 @@ public class ForgeHooksClient
segment.clear(); segment.clear();
} }
private static int getColorMultiplier(ItemStack stack, int tintIndex)
{
if (tintIndex == -1 || stack.isEmpty()) return 0xFFFFFFFF;
int colorMultiplier = Minecraft.getInstance().getItemColors().getColor(stack, tintIndex);
// Always full opacity
colorMultiplier |= 0xff << 24; // -16777216
return colorMultiplier;
}
/** /**
* internal, relies on fixed format of FaceBakery * internal, relies on fixed format of FaceBakery
*/ */