001 package net.minecraft.client.renderer.entity; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import net.minecraft.block.Block; 006 import net.minecraft.client.gui.FontRenderer; 007 import net.minecraft.client.model.ModelBase; 008 import net.minecraft.client.model.ModelBiped; 009 import net.minecraft.client.renderer.RenderBlocks; 010 import net.minecraft.client.renderer.RenderEngine; 011 import net.minecraft.client.renderer.Tessellator; 012 import net.minecraft.entity.Entity; 013 import net.minecraft.entity.EntityLiving; 014 import net.minecraft.util.AxisAlignedBB; 015 import net.minecraft.util.MathHelper; 016 import net.minecraft.world.World; 017 import org.lwjgl.opengl.GL11; 018 019 @SideOnly(Side.CLIENT) 020 public abstract class Render 021 { 022 protected RenderManager renderManager; 023 private ModelBase modelBase = new ModelBiped(); 024 protected RenderBlocks renderBlocks = new RenderBlocks(); 025 protected float shadowSize = 0.0F; 026 027 /** 028 * Determines the darkness of the object's shadow. Higher value makes a darker shadow. 029 */ 030 protected float shadowOpaque = 1.0F; 031 032 /** 033 * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then 034 * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic 035 * (Render<T extends Entity) and this method has signature public void doRender(T entity, double d, double d1, 036 * double d2, float f, float f1). But JAD is pre 1.5 so doesn't do that. 037 */ 038 public abstract void doRender(Entity var1, double var2, double var4, double var6, float var8, float var9); 039 040 /** 041 * loads the specified texture 042 */ 043 protected void loadTexture(String par1Str) 044 { 045 RenderEngine var2 = this.renderManager.renderEngine; 046 var2.bindTexture(var2.getTexture(par1Str)); 047 } 048 049 /** 050 * loads the specified downloadable texture or alternative built in texture 051 */ 052 protected boolean loadDownloadableImageTexture(String par1Str, String par2Str) 053 { 054 RenderEngine var3 = this.renderManager.renderEngine; 055 int var4 = var3.getTextureForDownloadableImage(par1Str, par2Str); 056 057 if (var4 >= 0) 058 { 059 var3.bindTexture(var4); 060 return true; 061 } 062 else 063 { 064 return false; 065 } 066 } 067 068 /** 069 * Renders fire on top of the entity. Args: entity, x, y, z, partialTickTime 070 */ 071 private void renderEntityOnFire(Entity par1Entity, double par2, double par4, double par6, float par8) 072 { 073 GL11.glDisable(GL11.GL_LIGHTING); 074 int var9 = Block.fire.blockIndexInTexture; 075 int var10 = (var9 & 15) << 4; 076 int var11 = var9 & 240; 077 float var12 = (float)var10 / 256.0F; 078 float var13 = ((float)var10 + 15.99F) / 256.0F; 079 float var14 = (float)var11 / 256.0F; 080 float var15 = ((float)var11 + 15.99F) / 256.0F; 081 GL11.glPushMatrix(); 082 GL11.glTranslatef((float)par2, (float)par4, (float)par6); 083 float var16 = par1Entity.width * 1.4F; 084 GL11.glScalef(var16, var16, var16); 085 this.loadTexture("/terrain.png"); 086 Tessellator var17 = Tessellator.instance; 087 float var18 = 0.5F; 088 float var19 = 0.0F; 089 float var20 = par1Entity.height / var16; 090 float var21 = (float)(par1Entity.posY - par1Entity.boundingBox.minY); 091 GL11.glRotatef(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); 092 GL11.glTranslatef(0.0F, 0.0F, -0.3F + (float)((int)var20) * 0.02F); 093 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 094 float var22 = 0.0F; 095 int var23 = 0; 096 var17.startDrawingQuads(); 097 098 while (var20 > 0.0F) 099 { 100 if (var23 % 2 == 0) 101 { 102 var12 = (float)var10 / 256.0F; 103 var13 = ((float)var10 + 15.99F) / 256.0F; 104 var14 = (float)var11 / 256.0F; 105 var15 = ((float)var11 + 15.99F) / 256.0F; 106 } 107 else 108 { 109 var12 = (float)var10 / 256.0F; 110 var13 = ((float)var10 + 15.99F) / 256.0F; 111 var14 = (float)(var11 + 16) / 256.0F; 112 var15 = ((float)(var11 + 16) + 15.99F) / 256.0F; 113 } 114 115 if (var23 / 2 % 2 == 0) 116 { 117 float var24 = var13; 118 var13 = var12; 119 var12 = var24; 120 } 121 122 var17.addVertexWithUV((double)(var18 - var19), (double)(0.0F - var21), (double)var22, (double)var13, (double)var15); 123 var17.addVertexWithUV((double)(-var18 - var19), (double)(0.0F - var21), (double)var22, (double)var12, (double)var15); 124 var17.addVertexWithUV((double)(-var18 - var19), (double)(1.4F - var21), (double)var22, (double)var12, (double)var14); 125 var17.addVertexWithUV((double)(var18 - var19), (double)(1.4F - var21), (double)var22, (double)var13, (double)var14); 126 var20 -= 0.45F; 127 var21 -= 0.45F; 128 var18 *= 0.9F; 129 var22 += 0.03F; 130 ++var23; 131 } 132 133 var17.draw(); 134 GL11.glPopMatrix(); 135 GL11.glEnable(GL11.GL_LIGHTING); 136 } 137 138 /** 139 * Renders the entity shadows at the position, shadow alpha and partialTickTime. Args: entity, x, y, z, shadowAlpha, 140 * partialTickTime 141 */ 142 private void renderShadow(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) 143 { 144 GL11.glEnable(GL11.GL_BLEND); 145 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 146 RenderEngine var10 = this.renderManager.renderEngine; 147 var10.bindTexture(var10.getTexture("%clamp%/misc/shadow.png")); 148 World var11 = this.getWorldFromRenderManager(); 149 GL11.glDepthMask(false); 150 float var12 = this.shadowSize; 151 152 if (par1Entity instanceof EntityLiving) 153 { 154 EntityLiving var13 = (EntityLiving)par1Entity; 155 var12 *= var13.getRenderSizeModifier(); 156 157 if (var13.isChild()) 158 { 159 var12 *= 0.5F; 160 } 161 } 162 163 double var36 = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par9; 164 double var15 = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par9 + (double)par1Entity.getShadowSize(); 165 double var17 = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par9; 166 int var19 = MathHelper.floor_double(var36 - (double)var12); 167 int var20 = MathHelper.floor_double(var36 + (double)var12); 168 int var21 = MathHelper.floor_double(var15 - (double)var12); 169 int var22 = MathHelper.floor_double(var15); 170 int var23 = MathHelper.floor_double(var17 - (double)var12); 171 int var24 = MathHelper.floor_double(var17 + (double)var12); 172 double var25 = par2 - var36; 173 double var27 = par4 - var15; 174 double var29 = par6 - var17; 175 Tessellator var31 = Tessellator.instance; 176 var31.startDrawingQuads(); 177 178 for (int var32 = var19; var32 <= var20; ++var32) 179 { 180 for (int var33 = var21; var33 <= var22; ++var33) 181 { 182 for (int var34 = var23; var34 <= var24; ++var34) 183 { 184 int var35 = var11.getBlockId(var32, var33 - 1, var34); 185 186 if (var35 > 0 && var11.getBlockLightValue(var32, var33, var34) > 3) 187 { 188 this.renderShadowOnBlock(Block.blocksList[var35], par2, par4 + (double)par1Entity.getShadowSize(), par6, var32, var33, var34, par8, var12, var25, var27 + (double)par1Entity.getShadowSize(), var29); 189 } 190 } 191 } 192 } 193 194 var31.draw(); 195 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 196 GL11.glDisable(GL11.GL_BLEND); 197 GL11.glDepthMask(true); 198 } 199 200 /** 201 * Returns the render manager's world object 202 */ 203 private World getWorldFromRenderManager() 204 { 205 return this.renderManager.worldObj; 206 } 207 208 /** 209 * Renders a shadow projected down onto the specified block. Brightness of the block plus how far away on the Y axis 210 * determines the alpha of the shadow. Args: block, centerX, centerY, centerZ, blockX, blockY, blockZ, baseAlpha, 211 * shadowSize, xOffset, yOffset, zOffset 212 */ 213 private void renderShadowOnBlock(Block par1Block, double par2, double par4, double par6, int par8, int par9, int par10, float par11, float par12, double par13, double par15, double par17) 214 { 215 Tessellator var19 = Tessellator.instance; 216 217 if (par1Block.renderAsNormalBlock()) 218 { 219 double var20 = ((double)par11 - (par4 - ((double)par9 + par15)) / 2.0D) * 0.5D * (double)this.getWorldFromRenderManager().getLightBrightness(par8, par9, par10); 220 221 if (var20 >= 0.0D) 222 { 223 if (var20 > 1.0D) 224 { 225 var20 = 1.0D; 226 } 227 228 var19.setColorRGBA_F(1.0F, 1.0F, 1.0F, (float)var20); 229 double var22 = (double)par8 + par1Block.getBlockBoundsMinX() + par13; 230 double var24 = (double)par8 + par1Block.getBlockBoundsMaxX() + par13; 231 double var26 = (double)par9 + par1Block.getBlockBoundsMinY() + par15 + 0.015625D; 232 double var28 = (double)par10 + par1Block.getBlockBoundsMinZ() + par17; 233 double var30 = (double)par10 + par1Block.getBlockBoundsMaxZ() + par17; 234 float var32 = (float)((par2 - var22) / 2.0D / (double)par12 + 0.5D); 235 float var33 = (float)((par2 - var24) / 2.0D / (double)par12 + 0.5D); 236 float var34 = (float)((par6 - var28) / 2.0D / (double)par12 + 0.5D); 237 float var35 = (float)((par6 - var30) / 2.0D / (double)par12 + 0.5D); 238 var19.addVertexWithUV(var22, var26, var28, (double)var32, (double)var34); 239 var19.addVertexWithUV(var22, var26, var30, (double)var32, (double)var35); 240 var19.addVertexWithUV(var24, var26, var30, (double)var33, (double)var35); 241 var19.addVertexWithUV(var24, var26, var28, (double)var33, (double)var34); 242 } 243 } 244 } 245 246 /** 247 * Renders a white box with the bounds of the AABB translated by the offset. Args: aabb, x, y, z 248 */ 249 public static void renderOffsetAABB(AxisAlignedBB par0AxisAlignedBB, double par1, double par3, double par5) 250 { 251 GL11.glDisable(GL11.GL_TEXTURE_2D); 252 Tessellator var7 = Tessellator.instance; 253 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 254 var7.startDrawingQuads(); 255 var7.setTranslation(par1, par3, par5); 256 var7.setNormal(0.0F, 0.0F, -1.0F); 257 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 258 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 259 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 260 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 261 var7.setNormal(0.0F, 0.0F, 1.0F); 262 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 263 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 264 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 265 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 266 var7.setNormal(0.0F, -1.0F, 0.0F); 267 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 268 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 269 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 270 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 271 var7.setNormal(0.0F, 1.0F, 0.0F); 272 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 273 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 274 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 275 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 276 var7.setNormal(-1.0F, 0.0F, 0.0F); 277 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 278 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 279 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 280 var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 281 var7.setNormal(1.0F, 0.0F, 0.0F); 282 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 283 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 284 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 285 var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 286 var7.setTranslation(0.0D, 0.0D, 0.0D); 287 var7.draw(); 288 GL11.glEnable(GL11.GL_TEXTURE_2D); 289 } 290 291 /** 292 * Adds to the tesselator a box using the aabb for the bounds. Args: aabb 293 */ 294 public static void renderAABB(AxisAlignedBB par0AxisAlignedBB) 295 { 296 Tessellator var1 = Tessellator.instance; 297 var1.startDrawingQuads(); 298 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 299 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 300 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 301 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 302 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 303 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 304 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 305 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 306 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 307 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 308 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 309 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 310 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 311 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 312 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 313 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 314 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 315 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 316 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 317 var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 318 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ); 319 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ); 320 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ); 321 var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ); 322 var1.draw(); 323 } 324 325 /** 326 * Sets the RenderManager. 327 */ 328 public void setRenderManager(RenderManager par1RenderManager) 329 { 330 this.renderManager = par1RenderManager; 331 } 332 333 /** 334 * Renders the entity's shadow and fire (if its on fire). Args: entity, x, y, z, yaw, partialTickTime 335 */ 336 public void doRenderShadowAndFire(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) 337 { 338 if (this.renderManager.options.fancyGraphics && this.shadowSize > 0.0F && !par1Entity.getHasActivePotion()) 339 { 340 double var10 = this.renderManager.getDistanceToCamera(par1Entity.posX, par1Entity.posY, par1Entity.posZ); 341 float var12 = (float)((1.0D - var10 / 256.0D) * (double)this.shadowOpaque); 342 343 if (var12 > 0.0F) 344 { 345 this.renderShadow(par1Entity, par2, par4, par6, var12, par9); 346 } 347 } 348 349 if (par1Entity.canRenderOnFire()) 350 { 351 this.renderEntityOnFire(par1Entity, par2, par4, par6, par9); 352 } 353 } 354 355 /** 356 * Returns the font renderer from the set render manager 357 */ 358 public FontRenderer getFontRendererFromRenderManager() 359 { 360 return this.renderManager.getFontRenderer(); 361 } 362 }