// // Decompiled by Procyon v0.5.36 // package com.mojang.minecraft.level; import com.mojang.minecraft.HitResult; import com.mojang.minecraft.phys.AABB; import com.mojang.minecraft.level.tile.Tile; import com.mojang.minecraft.renderer.Frustum; import java.util.Collections; import com.mojang.minecraft.renderer.Tesselator; import java.util.Comparator; import java.util.Arrays; import com.mojang.minecraft.Player; import java.util.ArrayList; import java.util.List; import org.lwjgl.opengl.GL11; import com.mojang.minecraft.renderer.Textures; public class LevelRenderer implements LevelListener { public static final int MAX_REBUILDS_PER_FRAME = 4; public static final int CHUNK_SIZE = 16; private Level level; private Chunk[] chunks; private Chunk[] sortedChunks; private int xChunks; private int yChunks; private int zChunks; private Textures textures; private int surroundLists; private int drawDistance; float lX; float lY; float lZ; public LevelRenderer(final Level level, final Textures textures) { this.drawDistance = 0; this.lX = 0.0f; this.lY = 0.0f; this.lZ = 0.0f; this.level = level; this.textures = textures; level.addListener(this); this.surroundLists = GL11.glGenLists(2); this.allChanged(); } public void allChanged() { this.lX = -900000.0f; this.lY = -900000.0f; this.lZ = -900000.0f; this.xChunks = (this.level.width + 16 - 1) / 16; this.yChunks = (this.level.depth + 16 - 1) / 16; this.zChunks = (this.level.height + 16 - 1) / 16; this.chunks = new Chunk[this.xChunks * this.yChunks * this.zChunks]; this.sortedChunks = new Chunk[this.xChunks * this.yChunks * this.zChunks]; for (int x = 0; x < this.xChunks; ++x) { for (int y = 0; y < this.yChunks; ++y) { for (int z = 0; z < this.zChunks; ++z) { final int x2 = x * 16; final int y2 = y * 16; final int z2 = z * 16; int x3 = (x + 1) * 16; int y3 = (y + 1) * 16; int z3 = (z + 1) * 16; if (x3 > this.level.width) { x3 = this.level.width; } if (y3 > this.level.depth) { y3 = this.level.depth; } if (z3 > this.level.height) { z3 = this.level.height; } this.chunks[(x + y * this.xChunks) * this.zChunks + z] = new Chunk(this.level, x2, y2, z2, x3, y3, z3); this.sortedChunks[(x + y * this.xChunks) * this.zChunks + z] = this.chunks[(x + y * this.xChunks) * this.zChunks + z]; } } } GL11.glNewList(this.surroundLists + 0, 4864); this.compileSurroundingGround(); GL11.glEndList(); GL11.glNewList(this.surroundLists + 1, 4864); this.compileSurroundingWater(); GL11.glEndList(); for (int i = 0; i < this.chunks.length; ++i) { this.chunks[i].reset(); } } public List getAllDirtyChunks() { ArrayList dirty = null; for (int i = 0; i < this.chunks.length; ++i) { final Chunk chunk = this.chunks[i]; if (chunk.isDirty()) { if (dirty == null) { dirty = new ArrayList(); } dirty.add(chunk); } } return dirty; } public void render(final Player player, final int layer) { GL11.glEnable(3553); GL11.glBindTexture(3553, this.textures.loadTexture("/terrain.png", 9728)); final float xd = player.x - this.lX; final float yd = player.y - this.lY; final float zd = player.z - this.lZ; if (xd * xd + yd * yd + zd * zd > 64.0f) { this.lX = player.x; this.lY = player.y; this.lZ = player.z; Arrays.sort(this.sortedChunks, new DistanceSorter(player)); } for (int i = 0; i < this.sortedChunks.length; ++i) { if (this.sortedChunks[i].visible) { final float dd = (float)(256 / (1 << this.drawDistance)); if (this.drawDistance == 0 || this.sortedChunks[i].distanceToSqr(player) < dd * dd) { this.sortedChunks[i].render(layer); } } } GL11.glDisable(3553); } public void renderSurroundingGround() { GL11.glCallList(this.surroundLists + 0); } public void compileSurroundingGround() { GL11.glEnable(3553); GL11.glBindTexture(3553, this.textures.loadTexture("/rock.png", 9728)); GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); final Tesselator t = Tesselator.instance; final float y = this.level.getGroundLevel() - 2.0f; int s = 128; if (s > this.level.width) { s = this.level.width; } if (s > this.level.height) { s = this.level.height; } final int d = 5; t.begin(); for (int xx = -s * d; xx < this.level.width + s * d; xx += s) { for (int zz = -s * d; zz < this.level.height + s * d; zz += s) { float yy = y; if (xx >= 0 && zz >= 0 && xx < this.level.width && zz < this.level.height) { yy = 0.0f; } t.vertexUV((float)(xx + 0), yy, (float)(zz + s), 0.0f, (float)s); t.vertexUV((float)(xx + s), yy, (float)(zz + s), (float)s, (float)s); t.vertexUV((float)(xx + s), yy, (float)(zz + 0), (float)s, 0.0f); t.vertexUV((float)(xx + 0), yy, (float)(zz + 0), 0.0f, 0.0f); } } t.end(); GL11.glBindTexture(3553, this.textures.loadTexture("/rock.png", 9728)); GL11.glColor3f(0.8f, 0.8f, 0.8f); t.begin(); for (int xx = 0; xx < this.level.width; xx += s) { t.vertexUV((float)(xx + 0), 0.0f, 0.0f, 0.0f, 0.0f); t.vertexUV((float)(xx + s), 0.0f, 0.0f, (float)s, 0.0f); t.vertexUV((float)(xx + s), y, 0.0f, (float)s, y); t.vertexUV((float)(xx + 0), y, 0.0f, 0.0f, y); t.vertexUV((float)(xx + 0), y, (float)this.level.height, 0.0f, y); t.vertexUV((float)(xx + s), y, (float)this.level.height, (float)s, y); t.vertexUV((float)(xx + s), 0.0f, (float)this.level.height, (float)s, 0.0f); t.vertexUV((float)(xx + 0), 0.0f, (float)this.level.height, 0.0f, 0.0f); } GL11.glColor3f(0.6f, 0.6f, 0.6f); for (int zz2 = 0; zz2 < this.level.height; zz2 += s) { t.vertexUV(0.0f, y, (float)(zz2 + 0), 0.0f, 0.0f); t.vertexUV(0.0f, y, (float)(zz2 + s), (float)s, 0.0f); t.vertexUV(0.0f, 0.0f, (float)(zz2 + s), (float)s, y); t.vertexUV(0.0f, 0.0f, (float)(zz2 + 0), 0.0f, y); t.vertexUV((float)this.level.width, 0.0f, (float)(zz2 + 0), 0.0f, y); t.vertexUV((float)this.level.width, 0.0f, (float)(zz2 + s), (float)s, y); t.vertexUV((float)this.level.width, y, (float)(zz2 + s), (float)s, 0.0f); t.vertexUV((float)this.level.width, y, (float)(zz2 + 0), 0.0f, 0.0f); } t.end(); GL11.glDisable(3042); GL11.glDisable(3553); } public void renderSurroundingWater() { GL11.glCallList(this.surroundLists + 1); } public void compileSurroundingWater() { GL11.glEnable(3553); GL11.glColor3f(1.0f, 1.0f, 1.0f); GL11.glBindTexture(3553, this.textures.loadTexture("/water.png", 9728)); final float y = this.level.getGroundLevel(); GL11.glEnable(3042); GL11.glBlendFunc(770, 771); final Tesselator t = Tesselator.instance; int s = 128; if (s > this.level.width) { s = this.level.width; } if (s > this.level.height) { s = this.level.height; } final int d = 5; t.begin(); for (int xx = -s * d; xx < this.level.width + s * d; xx += s) { for (int zz = -s * d; zz < this.level.height + s * d; zz += s) { final float yy = y - 0.1f; if (xx < 0 || zz < 0 || xx >= this.level.width || zz >= this.level.height) { t.vertexUV((float)(xx + 0), yy, (float)(zz + s), 0.0f, (float)s); t.vertexUV((float)(xx + s), yy, (float)(zz + s), (float)s, (float)s); t.vertexUV((float)(xx + s), yy, (float)(zz + 0), (float)s, 0.0f); t.vertexUV((float)(xx + 0), yy, (float)(zz + 0), 0.0f, 0.0f); t.vertexUV((float)(xx + 0), yy, (float)(zz + 0), 0.0f, 0.0f); t.vertexUV((float)(xx + s), yy, (float)(zz + 0), (float)s, 0.0f); t.vertexUV((float)(xx + s), yy, (float)(zz + s), (float)s, (float)s); t.vertexUV((float)(xx + 0), yy, (float)(zz + s), 0.0f, (float)s); } } } t.end(); GL11.glDisable(3042); GL11.glDisable(3553); } public void updateDirtyChunks(final Player player) { final List dirty = this.getAllDirtyChunks(); if (dirty == null) { return; } Collections.sort(dirty, new DirtyChunkSorter(player)); for (int i = 0; i < 4 && i < dirty.size(); ++i) { dirty.get(i).rebuild(); } } public void pick(final Player player, final Frustum frustum) { final Tesselator t = Tesselator.instance; final float r = 2.5f; final AABB box = player.bb.grow(r, r, r); final int x0 = (int)box.x0; final int x2 = (int)(box.x1 + 1.0f); final int y0 = (int)box.y0; final int y2 = (int)(box.y1 + 1.0f); final int z0 = (int)box.z0; final int z2 = (int)(box.z1 + 1.0f); GL11.glInitNames(); GL11.glPushName(0); GL11.glPushName(0); for (int x3 = x0; x3 < x2; ++x3) { GL11.glLoadName(x3); GL11.glPushName(0); for (int y3 = y0; y3 < y2; ++y3) { GL11.glLoadName(y3); GL11.glPushName(0); for (int z3 = z0; z3 < z2; ++z3) { final Tile tile = Tile.tiles[this.level.getTile(x3, y3, z3)]; if (tile != null && tile.mayPick() && frustum.isVisible(tile.getTileAABB(x3, y3, z3))) { GL11.glLoadName(z3); GL11.glPushName(0); for (int i = 0; i < 6; ++i) { GL11.glLoadName(i); t.begin(); tile.renderFaceNoTexture(player, t, x3, y3, z3, i); t.end(); } GL11.glPopName(); } } GL11.glPopName(); } GL11.glPopName(); } GL11.glPopName(); GL11.glPopName(); } public void renderHit(final Player player, final HitResult h, final int mode, final int tileType) { final Tesselator t = Tesselator.instance; GL11.glEnable(3042); GL11.glEnable(3008); GL11.glBlendFunc(770, 1); GL11.glColor4f(1.0f, 1.0f, 1.0f, ((float)Math.sin(System.currentTimeMillis() / 100.0) * 0.2f + 0.4f) * 0.5f); if (mode == 0) { t.begin(); for (int i = 0; i < 6; ++i) { Tile.rock.renderFaceNoTexture(player, t, h.x, h.y, h.z, i); } t.end(); } else { GL11.glBlendFunc(770, 771); final float br = (float)Math.sin(System.currentTimeMillis() / 100.0) * 0.2f + 0.8f; GL11.glColor4f(br, br, br, (float)Math.sin(System.currentTimeMillis() / 200.0) * 0.2f + 0.5f); GL11.glEnable(3553); final int id = this.textures.loadTexture("/terrain.png", 9728); GL11.glBindTexture(3553, id); int x = h.x; int y = h.y; int z = h.z; if (h.f == 0) { --y; } if (h.f == 1) { ++y; } if (h.f == 2) { --z; } if (h.f == 3) { ++z; } if (h.f == 4) { --x; } if (h.f == 5) { ++x; } t.begin(); t.noColor(); Tile.tiles[tileType].render(t, this.level, 0, x, y, z); Tile.tiles[tileType].render(t, this.level, 1, x, y, z); t.end(); GL11.glDisable(3553); } GL11.glDisable(3042); GL11.glDisable(3008); } public void renderHitOutline(final Player player, final HitResult h, final int mode, final int tileType) { GL11.glEnable(3042); GL11.glBlendFunc(770, 771); GL11.glColor4f(0.0f, 0.0f, 0.0f, 0.4f); float x = (float)h.x; float y = (float)h.y; float z = (float)h.z; if (mode == 1) { if (h.f == 0) { --y; } if (h.f == 1) { ++y; } if (h.f == 2) { --z; } if (h.f == 3) { ++z; } if (h.f == 4) { --x; } if (h.f == 5) { ++x; } } GL11.glBegin(3); GL11.glVertex3f(x, y, z); GL11.glVertex3f(x + 1.0f, y, z); GL11.glVertex3f(x + 1.0f, y, z + 1.0f); GL11.glVertex3f(x, y, z + 1.0f); GL11.glVertex3f(x, y, z); GL11.glEnd(); GL11.glBegin(3); GL11.glVertex3f(x, y + 1.0f, z); GL11.glVertex3f(x + 1.0f, y + 1.0f, z); GL11.glVertex3f(x + 1.0f, y + 1.0f, z + 1.0f); GL11.glVertex3f(x, y + 1.0f, z + 1.0f); GL11.glVertex3f(x, y + 1.0f, z); GL11.glEnd(); GL11.glBegin(1); GL11.glVertex3f(x, y, z); GL11.glVertex3f(x, y + 1.0f, z); GL11.glVertex3f(x + 1.0f, y, z); GL11.glVertex3f(x + 1.0f, y + 1.0f, z); GL11.glVertex3f(x + 1.0f, y, z + 1.0f); GL11.glVertex3f(x + 1.0f, y + 1.0f, z + 1.0f); GL11.glVertex3f(x, y, z + 1.0f); GL11.glVertex3f(x, y + 1.0f, z + 1.0f); GL11.glEnd(); GL11.glDisable(3042); } public void setDirty(int x0, int y0, int z0, int x1, int y1, int z1) { x0 /= 16; x1 /= 16; y0 /= 16; y1 /= 16; z0 /= 16; z1 /= 16; if (x0 < 0) { x0 = 0; } if (y0 < 0) { y0 = 0; } if (z0 < 0) { z0 = 0; } if (x1 >= this.xChunks) { x1 = this.xChunks - 1; } if (y1 >= this.yChunks) { y1 = this.yChunks - 1; } if (z1 >= this.zChunks) { z1 = this.zChunks - 1; } for (int x2 = x0; x2 <= x1; ++x2) { for (int y2 = y0; y2 <= y1; ++y2) { for (int z2 = z0; z2 <= z1; ++z2) { this.chunks[(x2 + y2 * this.xChunks) * this.zChunks + z2].setDirty(); } } } } public void tileChanged(final int x, final int y, final int z) { this.setDirty(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1); } public void lightColumnChanged(final int x, final int z, final int y0, final int y1) { this.setDirty(x - 1, y0 - 1, z - 1, x + 1, y1 + 1, z + 1); } public void toggleDrawDistance() { this.drawDistance = (this.drawDistance + 1) % 4; } public void cull(final Frustum frustum) { for (int i = 0; i < this.chunks.length; ++i) { this.chunks[i].visible = frustum.isVisible(this.chunks[i].aabb); } } }