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