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 instanceof EntityAnimal)
146                {
147                    EntityAnimal var14 = (EntityAnimal)var13;
148    
149                    if (var14.isChild())
150                    {
151                        var12 *= 0.5F;
152                    }
153                }
154            }
155    
156            double var36 = par1Entity.lastTickPosX + (par1Entity.posX - par1Entity.lastTickPosX) * (double)par9;
157            double var15 = par1Entity.lastTickPosY + (par1Entity.posY - par1Entity.lastTickPosY) * (double)par9 + (double)par1Entity.getShadowSize();
158            double var17 = par1Entity.lastTickPosZ + (par1Entity.posZ - par1Entity.lastTickPosZ) * (double)par9;
159            int var19 = MathHelper.floor_double(var36 - (double)var12);
160            int var20 = MathHelper.floor_double(var36 + (double)var12);
161            int var21 = MathHelper.floor_double(var15 - (double)var12);
162            int var22 = MathHelper.floor_double(var15);
163            int var23 = MathHelper.floor_double(var17 - (double)var12);
164            int var24 = MathHelper.floor_double(var17 + (double)var12);
165            double var25 = par2 - var36;
166            double var27 = par4 - var15;
167            double var29 = par6 - var17;
168            Tessellator var31 = Tessellator.instance;
169            var31.startDrawingQuads();
170    
171            for (int var32 = var19; var32 <= var20; ++var32)
172            {
173                for (int var33 = var21; var33 <= var22; ++var33)
174                {
175                    for (int var34 = var23; var34 <= var24; ++var34)
176                    {
177                        int var35 = var11.getBlockId(var32, var33 - 1, var34);
178    
179                        if (var35 > 0 && var11.getBlockLightValue(var32, var33, var34) > 3)
180                        {
181                            this.renderShadowOnBlock(Block.blocksList[var35], par2, par4 + (double)par1Entity.getShadowSize(), par6, var32, var33, var34, par8, var12, var25, var27 + (double)par1Entity.getShadowSize(), var29);
182                        }
183                    }
184                }
185            }
186    
187            var31.draw();
188            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
189            GL11.glDisable(GL11.GL_BLEND);
190            GL11.glDepthMask(true);
191        }
192    
193        /**
194         * Returns the render manager's world object
195         */
196        private World getWorldFromRenderManager()
197        {
198            return this.renderManager.worldObj;
199        }
200    
201        /**
202         * Renders a shadow projected down onto the specified block. Brightness of the block plus how far away on the Y axis
203         * determines the alpha of the shadow.  Args: block, centerX, centerY, centerZ, blockX, blockY, blockZ, baseAlpha,
204         * shadowSize, xOffset, yOffset, zOffset
205         */
206        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)
207        {
208            Tessellator var19 = Tessellator.instance;
209    
210            if (par1Block.renderAsNormalBlock())
211            {
212                double var20 = ((double)par11 - (par4 - ((double)par9 + par15)) / 2.0D) * 0.5D * (double)this.getWorldFromRenderManager().getLightBrightness(par8, par9, par10);
213    
214                if (var20 >= 0.0D)
215                {
216                    if (var20 > 1.0D)
217                    {
218                        var20 = 1.0D;
219                    }
220    
221                    var19.setColorRGBA_F(1.0F, 1.0F, 1.0F, (float)var20);
222                    double var22 = (double)par8 + par1Block.minX + par13;
223                    double var24 = (double)par8 + par1Block.maxX + par13;
224                    double var26 = (double)par9 + par1Block.minY + par15 + 0.015625D;
225                    double var28 = (double)par10 + par1Block.minZ + par17;
226                    double var30 = (double)par10 + par1Block.maxZ + par17;
227                    float var32 = (float)((par2 - var22) / 2.0D / (double)par12 + 0.5D);
228                    float var33 = (float)((par2 - var24) / 2.0D / (double)par12 + 0.5D);
229                    float var34 = (float)((par6 - var28) / 2.0D / (double)par12 + 0.5D);
230                    float var35 = (float)((par6 - var30) / 2.0D / (double)par12 + 0.5D);
231                    var19.addVertexWithUV(var22, var26, var28, (double)var32, (double)var34);
232                    var19.addVertexWithUV(var22, var26, var30, (double)var32, (double)var35);
233                    var19.addVertexWithUV(var24, var26, var30, (double)var33, (double)var35);
234                    var19.addVertexWithUV(var24, var26, var28, (double)var33, (double)var34);
235                }
236            }
237        }
238    
239        /**
240         * Renders a white box with the bounds of the AABB translated by the offset. Args: aabb, x, y, z
241         */
242        public static void renderOffsetAABB(AxisAlignedBB par0AxisAlignedBB, double par1, double par3, double par5)
243        {
244            GL11.glDisable(GL11.GL_TEXTURE_2D);
245            Tessellator var7 = Tessellator.instance;
246            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
247            var7.startDrawingQuads();
248            var7.setTranslation(par1, par3, par5);
249            var7.setNormal(0.0F, 0.0F, -1.0F);
250            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
251            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
252            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
253            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
254            var7.setNormal(0.0F, 0.0F, 1.0F);
255            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
256            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
257            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
258            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
259            var7.setNormal(0.0F, -1.0F, 0.0F);
260            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
261            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
262            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
263            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
264            var7.setNormal(0.0F, 1.0F, 0.0F);
265            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
266            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
267            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
268            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
269            var7.setNormal(-1.0F, 0.0F, 0.0F);
270            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
271            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
272            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
273            var7.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
274            var7.setNormal(1.0F, 0.0F, 0.0F);
275            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
276            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
277            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
278            var7.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
279            var7.setTranslation(0.0D, 0.0D, 0.0D);
280            var7.draw();
281            GL11.glEnable(GL11.GL_TEXTURE_2D);
282        }
283    
284        /**
285         * Adds to the tesselator a box using the aabb for the bounds. Args: aabb
286         */
287        public static void renderAABB(AxisAlignedBB par0AxisAlignedBB)
288        {
289            Tessellator var1 = Tessellator.instance;
290            var1.startDrawingQuads();
291            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
292            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
293            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
294            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
295            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
296            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
297            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
298            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
299            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
300            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
301            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
302            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
303            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
304            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
305            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
306            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
307            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
308            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
309            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
310            var1.addVertex(par0AxisAlignedBB.minX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
311            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.minZ);
312            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.minZ);
313            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.maxY, par0AxisAlignedBB.maxZ);
314            var1.addVertex(par0AxisAlignedBB.maxX, par0AxisAlignedBB.minY, par0AxisAlignedBB.maxZ);
315            var1.draw();
316        }
317    
318        /**
319         * Sets the RenderManager.
320         */
321        public void setRenderManager(RenderManager par1RenderManager)
322        {
323            this.renderManager = par1RenderManager;
324        }
325    
326        /**
327         * Renders the entity's shadow and fire (if its on fire). Args: entity, x, y, z, yaw, partialTickTime
328         */
329        public void doRenderShadowAndFire(Entity par1Entity, double par2, double par4, double par6, float par8, float par9)
330        {
331            if (this.renderManager.options.fancyGraphics && this.shadowSize > 0.0F)
332            {
333                double var10 = this.renderManager.getDistanceToCamera(par1Entity.posX, par1Entity.posY, par1Entity.posZ);
334                float var12 = (float)((1.0D - var10 / 256.0D) * (double)this.shadowOpaque);
335    
336                if (var12 > 0.0F)
337                {
338                    this.renderShadow(par1Entity, par2, par4, par6, var12, par9);
339                }
340            }
341    
342            if (par1Entity.isBurning())
343            {
344                this.renderEntityOnFire(par1Entity, par2, par4, par6, par9);
345            }
346        }
347    
348        /**
349         * Returns the font renderer from the set render manager
350         */
351        public FontRenderer getFontRendererFromRenderManager()
352        {
353            return this.renderManager.getFontRenderer();
354        }
355    }