implement item renderer, add debug information to overlay
This commit is contained in:
@@ -25,9 +25,15 @@ window.GameWindow = class {
|
|||||||
this.wrapper.appendChild(this.canvasItems);
|
this.wrapper.appendChild(this.canvasItems);
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
this.stats = new Stats()
|
this.statsFps = new Stats()
|
||||||
this.stats.showPanel(0);
|
this.statsFps.showPanel(0);
|
||||||
this.wrapper.appendChild(this.stats.dom);
|
this.statsFps.domElement.style.cssText = 'position:absolute;top:0px;right:80px;float:right';
|
||||||
|
this.wrapper.appendChild(this.statsFps.dom);
|
||||||
|
|
||||||
|
this.statsMs = new Stats()
|
||||||
|
this.statsMs.showPanel(1);
|
||||||
|
this.statsMs.domElement.style.cssText = 'position:absolute;top:0px;right:160px;float:right';
|
||||||
|
this.wrapper.appendChild(this.statsMs.dom);
|
||||||
|
|
||||||
// On resize
|
// On resize
|
||||||
let scope = this;
|
let scope = this;
|
||||||
@@ -112,12 +118,18 @@ window.GameWindow = class {
|
|||||||
let wrapperHeight = this.height * this.scaleFactor;
|
let wrapperHeight = this.height * this.scaleFactor;
|
||||||
|
|
||||||
let worldRenderer = this.minecraft.worldRenderer;
|
let worldRenderer = this.minecraft.worldRenderer;
|
||||||
|
let itemRenderer = this.minecraft.itemRenderer;
|
||||||
|
|
||||||
// Update world renderer size and camera
|
// Update world renderer size and camera
|
||||||
worldRenderer.camera.aspect = this.width / this.height;
|
worldRenderer.camera.aspect = this.width / this.height;
|
||||||
worldRenderer.camera.updateProjectionMatrix();
|
worldRenderer.camera.updateProjectionMatrix();
|
||||||
worldRenderer.webRenderer.setSize(wrapperWidth, wrapperHeight);
|
worldRenderer.webRenderer.setSize(wrapperWidth, wrapperHeight);
|
||||||
|
|
||||||
|
// Update item renderer size and camera
|
||||||
|
itemRenderer.camera.aspect = this.width / this.height;
|
||||||
|
itemRenderer.camera.updateProjectionMatrix();
|
||||||
|
itemRenderer.webRenderer.setSize(wrapperWidth, wrapperHeight);
|
||||||
|
|
||||||
// Update canvas 2d size
|
// Update canvas 2d size
|
||||||
this.canvas2d.style.width = wrapperWidth + "px";
|
this.canvas2d.style.width = wrapperWidth + "px";
|
||||||
this.canvas2d.style.height = wrapperHeight + "px";
|
this.canvas2d.style.height = wrapperHeight + "px";
|
||||||
|
|||||||
@@ -7,24 +7,23 @@ window.Minecraft = class {
|
|||||||
this.currentScreen = null;
|
this.currentScreen = null;
|
||||||
this.loadingScreen = null;
|
this.loadingScreen = null;
|
||||||
|
|
||||||
// Create window and world renderer
|
// Tick timer
|
||||||
this.window = new GameWindow(this, canvasWrapperId);
|
|
||||||
this.worldRenderer = new WorldRenderer(this, this.window);
|
|
||||||
this.timer = new Timer(20);
|
this.timer = new Timer(20);
|
||||||
|
|
||||||
// Create screen renderer
|
// Create window and world renderer
|
||||||
|
this.window = new GameWindow(this, canvasWrapperId);
|
||||||
|
|
||||||
|
// Create renderers
|
||||||
|
this.worldRenderer = new WorldRenderer(this, this.window);
|
||||||
this.screenRenderer = new ScreenRenderer(this, this.window);
|
this.screenRenderer = new ScreenRenderer(this, this.window);
|
||||||
|
this.itemRenderer = new ItemRenderer(this, this.window);
|
||||||
|
|
||||||
// Create current screen and overlay
|
// Create current screen and overlay
|
||||||
this.ingameOverlay = new IngameOverlay(this, this.window);
|
this.ingameOverlay = new IngameOverlay(this, this.window);
|
||||||
|
|
||||||
// Update window size
|
|
||||||
this.window.updateWindowSize();
|
|
||||||
|
|
||||||
// Display loading screen
|
// Display loading screen
|
||||||
this.loadingScreen = new GuiLoadingScreen();
|
this.loadingScreen = new GuiLoadingScreen();
|
||||||
this.loadingScreen.setTitle("Building terrain...");
|
this.loadingScreen.setTitle("Building terrain...");
|
||||||
this.displayScreen(this.loadingScreen);
|
|
||||||
|
|
||||||
this.frames = 0;
|
this.frames = 0;
|
||||||
this.lastTime = Date.now();
|
this.lastTime = Date.now();
|
||||||
@@ -32,6 +31,11 @@ window.Minecraft = class {
|
|||||||
// Create all blocks
|
// Create all blocks
|
||||||
Block.create();
|
Block.create();
|
||||||
|
|
||||||
|
this.itemRenderer.initialize();
|
||||||
|
|
||||||
|
// Update window size
|
||||||
|
this.window.updateWindowSize();
|
||||||
|
|
||||||
// Create world
|
// Create world
|
||||||
this.world = new World(this);
|
this.world = new World(this);
|
||||||
this.worldRenderer.scene.add(this.world.group);
|
this.worldRenderer.scene.add(this.world.group);
|
||||||
@@ -40,6 +44,8 @@ window.Minecraft = class {
|
|||||||
this.player = new Player(this, this.world);
|
this.player = new Player(this, this.world);
|
||||||
this.inventory = new Inventory();
|
this.inventory = new Inventory();
|
||||||
|
|
||||||
|
this.displayScreen(this.loadingScreen);
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -69,7 +75,8 @@ window.Minecraft = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onLoop() {
|
onLoop() {
|
||||||
this.window.stats.begin();
|
this.window.statsFps.begin();
|
||||||
|
this.window.statsMs.begin();
|
||||||
|
|
||||||
// Update the timer
|
// Update the timer
|
||||||
this.timer.advanceTime();
|
this.timer.advanceTime();
|
||||||
@@ -93,7 +100,8 @@ window.Minecraft = class {
|
|||||||
this.frames = 0;
|
this.frames = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.window.stats.end();
|
this.window.statsFps.end();
|
||||||
|
this.window.statsMs.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
onRender(partialTicks) {
|
onRender(partialTicks) {
|
||||||
@@ -113,6 +121,7 @@ window.Minecraft = class {
|
|||||||
// Render the game
|
// Render the game
|
||||||
this.worldRenderer.render(partialTicks);
|
this.worldRenderer.render(partialTicks);
|
||||||
this.screenRenderer.render(partialTicks);
|
this.screenRenderer.render(partialTicks);
|
||||||
|
this.itemRenderer.render(partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayScreen(screen) {
|
displayScreen(screen) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ window.IngameOverlay = class extends Gui {
|
|||||||
|
|
||||||
this.textureCrosshair = Gui.loadTexture("icons.png");
|
this.textureCrosshair = Gui.loadTexture("icons.png");
|
||||||
this.textureHotbar = Gui.loadTexture("gui.png");
|
this.textureHotbar = Gui.loadTexture("gui.png");
|
||||||
this.textureTerrain = Gui.loadTexture("terrain.png");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render(stack, mouseX, mouseY, partialTicks) {
|
render(stack, mouseX, mouseY, partialTicks) {
|
||||||
@@ -15,7 +14,14 @@ window.IngameOverlay = class extends Gui {
|
|||||||
this.renderCrosshair(stack, this.window.width / 2, this.window.height / 2)
|
this.renderCrosshair(stack, this.window.width / 2, this.window.height / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.renderHotbar(stack, this.window.width / 2 - 100, this.window.height - 22);
|
this.renderHotbar(stack, this.window.width / 2 - 91, this.window.height - 22);
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
this.drawString(stack, Math.floor(this.minecraft.timer.fps) + " fps," +
|
||||||
|
" " + this.minecraft.world.lightUpdateQueue.length + " light updates," +
|
||||||
|
" " + this.minecraft.worldRenderer.chunkSectionUpdateQueue.length + " chunk updates", 1, 1);
|
||||||
|
this.drawString(stack, Math.floor(this.minecraft.player.x) + ", " + Math.floor(this.minecraft.player.y) + ", " + Math.floor(this.minecraft.player.z)
|
||||||
|
+ " (" + Math.floor(this.minecraft.player.x >> 4) + ", " + Math.floor(this.minecraft.player.y >> 4) + ", " + Math.floor(this.minecraft.player.z >> 4) + ")", 1, 1 + 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCrosshair(stack, x, y) {
|
renderCrosshair(stack, x, y) {
|
||||||
@@ -24,6 +30,7 @@ window.IngameOverlay = class extends Gui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderHotbar(stack, x, y) {
|
renderHotbar(stack, x, y) {
|
||||||
|
// Render background
|
||||||
this.drawSprite(stack, this.textureHotbar, 0, 0, 200, 22, x, y, 200, 22)
|
this.drawSprite(stack, this.textureHotbar, 0, 0, 200, 22, x, y, 200, 22)
|
||||||
this.drawSprite(
|
this.drawSprite(
|
||||||
stack,
|
stack,
|
||||||
@@ -34,23 +41,13 @@ window.IngameOverlay = class extends Gui {
|
|||||||
24, 24
|
24, 24
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Render items
|
||||||
for (let i = 0; i < 9; i++) {
|
for (let i = 0; i < 9; i++) {
|
||||||
let typeId = this.minecraft.inventory.getItemInSlot(i);
|
let typeId = this.minecraft.inventory.getItemInSlot(i);
|
||||||
|
|
||||||
if (typeId !== 0) {
|
if (typeId !== 0) {
|
||||||
/*this.renderBlock(
|
let renderId = "hotbar" + i;
|
||||||
stack,
|
let block = Block.getById(typeId);
|
||||||
this.textureTerrain, Block.getById(typeId),
|
this.minecraft.itemRenderer.renderItemInGui(renderId, block, x + i * 20 + 11, y + 11);
|
||||||
x + i * 20 + 11,
|
|
||||||
y + 9
|
|
||||||
);*/
|
|
||||||
|
|
||||||
// UV Mapping
|
|
||||||
let textureIndex = Block.getById(typeId).getTextureForFace(EnumBlockFace.NORTH);
|
|
||||||
let minU = (textureIndex % 16) / 16.0;
|
|
||||||
let minV = Math.floor(textureIndex / 16) / 16.0;
|
|
||||||
|
|
||||||
this.drawSprite(stack, this.textureTerrain, minU * 256, minV, 16, 16, x + 3 + i * 20, y + 3, 16, 16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ window.BlockRenderer = class {
|
|||||||
this.tessellator.bindTexture(worldRenderer.terrainTexture);
|
this.tessellator.bindTexture(worldRenderer.terrainTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderBlock(world, group, block, x, y, z) {
|
renderBlock(world, block, x, y, z) {
|
||||||
let boundingBox = block.getBoundingBox(world, x, y, z);
|
let boundingBox = block.getBoundingBox(world, x, y, z);
|
||||||
|
|
||||||
// Render all faces
|
// Render all faces
|
||||||
@@ -47,7 +47,8 @@ window.BlockRenderer = class {
|
|||||||
|
|
||||||
// Classic lightning
|
// Classic lightning
|
||||||
if (BlockRenderer.CLASSIC_LIGHTNING) {
|
if (BlockRenderer.CLASSIC_LIGHTNING) {
|
||||||
let brightness = 0.9 / 15.0 * world.getTotalLightAt(minX + face.x, minY + face.y, minZ + face.z) + 0.1;
|
let level = world === null ? 15 : world.getTotalLightAt(minX + face.x, minY + face.y, minZ + face.z);
|
||||||
|
let brightness = 0.9 / 15.0 * level + 0.1;
|
||||||
let color = brightness * face.getShading();
|
let color = brightness * face.getShading();
|
||||||
this.tessellator.setColor(color, color, color);
|
this.tessellator.setColor(color, color, color);
|
||||||
}
|
}
|
||||||
@@ -112,6 +113,10 @@ window.BlockRenderer = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getAverageLightLevelAt(world, x, y, z) {
|
getAverageLightLevelAt(world, x, y, z) {
|
||||||
|
if (world === null) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
|
||||||
let totalLightLevel = 0;
|
let totalLightLevel = 0;
|
||||||
let totalBlocks = 0;
|
let totalBlocks = 0;
|
||||||
|
|
||||||
@@ -135,4 +140,28 @@ window.BlockRenderer = class {
|
|||||||
// Calculate the average light level of all surrounding blocks
|
// Calculate the average light level of all surrounding blocks
|
||||||
return totalBlocks === 0 ? 0 : totalLightLevel / totalBlocks;
|
return totalBlocks === 0 ? 0 : totalLightLevel / totalBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderGuiBlock(group, block, x, y, size) {
|
||||||
|
this.tessellator.startDrawing();
|
||||||
|
|
||||||
|
let boundingBox = block.getBoundingBox(null, 0, 0, 0);
|
||||||
|
this.renderFace(null, block, boundingBox, EnumBlockFace.TOP, 0, 0, 0);
|
||||||
|
this.renderFace(null, block, boundingBox, EnumBlockFace.NORTH, 0, 0, 0);
|
||||||
|
this.renderFace(null, block, boundingBox, EnumBlockFace.EAST, 0, 0, 0);
|
||||||
|
|
||||||
|
let mesh = this.tessellator.draw(group);
|
||||||
|
mesh.geometry.center();
|
||||||
|
|
||||||
|
mesh.rotation.x = -MathHelper.toRadians(45 / 1.5);
|
||||||
|
mesh.rotation.y = MathHelper.toRadians(45);
|
||||||
|
|
||||||
|
mesh.position.x = x;
|
||||||
|
mesh.position.y = -y;
|
||||||
|
mesh.position.z = -3;
|
||||||
|
|
||||||
|
//let scale = Math.cos(Date.now() / 1000) * 100;
|
||||||
|
mesh.scale.x = size;
|
||||||
|
mesh.scale.y = size;
|
||||||
|
mesh.scale.z = size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,8 @@ window.Tessellator = class {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.material = new THREE.MeshBasicMaterial({
|
this.material = new THREE.MeshBasicMaterial({
|
||||||
vertexColors: THREE.VertexColors,
|
vertexColors: THREE.VertexColors,
|
||||||
side: THREE.BackSide,
|
//side: THREE.BackSide,
|
||||||
|
side: THREE.DoubleSide,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
depthTest: true
|
depthTest: true
|
||||||
});
|
});
|
||||||
@@ -66,6 +67,7 @@ window.Tessellator = class {
|
|||||||
let mesh = new THREE.Mesh(geometry, this.material);
|
let mesh = new THREE.Mesh(geometry, this.material);
|
||||||
group.matrixAutoUpdate = false;
|
group.matrixAutoUpdate = false;
|
||||||
group.add(mesh);
|
group.add(mesh);
|
||||||
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -15,6 +15,10 @@ window.WorldRenderer = class {
|
|||||||
// Block Renderer
|
// Block Renderer
|
||||||
this.blockRenderer = new BlockRenderer(this);
|
this.blockRenderer = new BlockRenderer(this);
|
||||||
|
|
||||||
|
this.initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
// Create world camera
|
// Create world camera
|
||||||
this.camera = new THREE.PerspectiveCamera(0, 1, 0.001, 1000);
|
this.camera = new THREE.PerspectiveCamera(0, 1, 0.001, 1000);
|
||||||
this.camera.rotation.order = 'ZYX';
|
this.camera.rotation.order = 'ZYX';
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
window.ItemRenderer = class {
|
||||||
|
|
||||||
|
constructor(minecraft, window) {
|
||||||
|
this.minecraft = minecraft;
|
||||||
|
this.window = window;
|
||||||
|
|
||||||
|
this.items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
// Create item camera
|
||||||
|
this.camera = new THREE.OrthographicCamera(0, 0, 0, 0, 0, 300);
|
||||||
|
this.camera.near = 0;
|
||||||
|
this.camera.far = 15;
|
||||||
|
this.camera.rotation.order = 'ZYX';
|
||||||
|
this.camera.up = new THREE.Vector3(0, 1, 0);
|
||||||
|
|
||||||
|
// Create scene
|
||||||
|
this.scene = new THREE.Scene();
|
||||||
|
this.scene.matrixAutoUpdate = false;
|
||||||
|
|
||||||
|
// Create web renderer
|
||||||
|
this.webRenderer = new THREE.WebGLRenderer({
|
||||||
|
canvas: this.window.canvasItems,
|
||||||
|
antialias: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
this.webRenderer.setSize(this.window.width, this.window.height);
|
||||||
|
this.webRenderer.shadowMap.enabled = true;
|
||||||
|
this.webRenderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
|
||||||
|
this.webRenderer.autoClear = false;
|
||||||
|
this.webRenderer.sortObjects = false;
|
||||||
|
this.webRenderer.setClearColor(0x000000, 0);
|
||||||
|
this.webRenderer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
render(partialTicks) {
|
||||||
|
// Update camera
|
||||||
|
this.camera.left = -this.window.width / 2;
|
||||||
|
this.camera.right = this.window.width / 2;
|
||||||
|
this.camera.top = this.window.height / 2;
|
||||||
|
this.camera.bottom = -this.window.height / 2;
|
||||||
|
this.camera.setViewOffset(this.window.width, this.window.height, this.window.width / 2, this.window.height / 2, this.window.width, this.window.height);
|
||||||
|
this.camera.updateProjectionMatrix();
|
||||||
|
|
||||||
|
// Render scene
|
||||||
|
this.webRenderer.render(this.scene, this.camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItemInGui(renderId, block, x, y) {
|
||||||
|
let meta = this.items[renderId];
|
||||||
|
if (typeof meta === "undefined") {
|
||||||
|
let meta = {};
|
||||||
|
|
||||||
|
let group = new THREE.Group();
|
||||||
|
this.minecraft.worldRenderer.blockRenderer.renderGuiBlock(group, block, x, y, 10);
|
||||||
|
this.scene.add(group);
|
||||||
|
|
||||||
|
meta.group = group;
|
||||||
|
meta.typeId = block.getId();
|
||||||
|
meta.x = x;
|
||||||
|
meta.y = y;
|
||||||
|
this.items[renderId] = meta;
|
||||||
|
} else {
|
||||||
|
if (meta.typeId !== block.getId() || meta.x !== x || meta.y !== y) {
|
||||||
|
this.scene.remove(meta.group);
|
||||||
|
delete this.items[renderId];
|
||||||
|
this.renderItemInGui(renderId, block, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ window.ChunkSection = class {
|
|||||||
let absoluteZ = this.z * ChunkSection.SIZE + z;
|
let absoluteZ = this.z * ChunkSection.SIZE + z;
|
||||||
|
|
||||||
let block = Block.getById(typeId);
|
let block = Block.getById(typeId);
|
||||||
renderer.blockRenderer.renderBlock(this.world, this.group, block, absoluteX, absoluteY, absoluteZ);
|
renderer.blockRenderer.renderBlock(this.world, block, absoluteX, absoluteY, absoluteZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ loadScripts([
|
|||||||
"src/js/net/minecraft/client/render/isometric/Triangle.js",
|
"src/js/net/minecraft/client/render/isometric/Triangle.js",
|
||||||
"src/js/net/minecraft/client/render/gui/FontRenderer.js",
|
"src/js/net/minecraft/client/render/gui/FontRenderer.js",
|
||||||
"src/js/net/minecraft/client/render/gui/ScreenRenderer.js",
|
"src/js/net/minecraft/client/render/gui/ScreenRenderer.js",
|
||||||
|
"src/js/net/minecraft/client/render/gui/ItemRenderer.js",
|
||||||
"src/js/net/minecraft/client/render/Tessellator.js",
|
"src/js/net/minecraft/client/render/Tessellator.js",
|
||||||
"src/js/net/minecraft/client/render/WorldRenderer.js",
|
"src/js/net/minecraft/client/render/WorldRenderer.js",
|
||||||
"src/js/net/minecraft/client/render/BlockRenderer.js"
|
"src/js/net/minecraft/client/render/BlockRenderer.js"
|
||||||
|
|||||||
Reference in New Issue
Block a user