diff --git a/src/js/net/minecraft/client/GameWindow.js b/src/js/net/minecraft/client/GameWindow.js index f77f241..0b86686 100644 --- a/src/js/net/minecraft/client/GameWindow.js +++ b/src/js/net/minecraft/client/GameWindow.js @@ -49,18 +49,14 @@ export default class GameWindow { this.wrapper.removeChild(this.wrapper.firstChild); } - // Create world renderer + // Create render layers + this.canvasWorld = document.createElement('canvas'); + this.canvasDebug = document.createElement('canvas'); + this.canvasItems = document.createElement('canvas'); + + // Create canvas renderer this.canvas = document.createElement('canvas'); this.wrapper.appendChild(this.canvas); - - // Create screen renderer - this.canvas2d = document.createElement('canvas'); - this.canvas2d.debugCanvas = document.createElement('canvas'); - this.wrapper.appendChild(this.canvas2d); - - // Create screen item renderer - this.canvasItems = document.createElement('canvas'); - this.wrapper.appendChild(this.canvasItems); } registerDesktopListeners() { @@ -376,12 +372,11 @@ export default class GameWindow { itemRenderer.webRenderer.setSize(wrapperWidth, wrapperHeight); // Update canvas 2d size - this.canvas2d.style.width = wrapperWidth + "px"; - this.canvas2d.style.height = wrapperHeight + "px"; + this.canvas.style.width = wrapperWidth + "px"; + this.canvas.style.height = wrapperHeight + "px"; - let debugCanvas = this.canvas2d["debugCanvas"]; - debugCanvas.width = this.canvas2d.width; - debugCanvas.height = this.canvas2d.height; + this.canvasDebug.width = this.canvas.width; + this.canvasDebug.height = this.canvas.height; // Reinitialize gui this.minecraft.screenRenderer.initialize(); @@ -390,6 +385,11 @@ export default class GameWindow { if (this.minecraft.currentScreen !== null) { this.minecraft.currentScreen.setup(this.minecraft, this.width, this.height); } + + // Render first frame + if (this.minecraft.isInGame()) { + this.minecraft.worldRenderer.render(0); + } } updateScaleFactor() { @@ -492,7 +492,7 @@ export default class GameWindow { } getGPUName() { - let gl = this.canvas.getContext("webgl2"); + let gl = this.canvasWorld.getContext("webgl2"); const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); return gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); } diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index a80ed9a..741c757 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -25,7 +25,7 @@ import FocusStateType from "../util/FocusStateType.js"; export default class Minecraft { - static VERSION = "1.1.2" + static VERSION = "1.1.3" static URL_GITHUB = "https://github.com/labystudio/js-minecraft"; static PROTOCOL_VERSION = 758; @@ -161,7 +161,13 @@ export default class Minecraft { onLoop() { // Update the timer - this.timer.advanceTime(); + if (this.isPaused() && this.isInGame()) { + let prevPartialTicks = this.timer.partialTicks; + this.timer.advanceTime(); + this.timer.partialTicks = prevPartialTicks; + } else { + this.timer.advanceTime(); + } // Call the tick to reach updates 20 per seconds for (let i = 0; i < this.timer.ticks; i++) { @@ -169,7 +175,7 @@ export default class Minecraft { } // Render the game - this.onRender(this.isPaused() ? 0 : this.timer.partialTicks); + this.onRender(this.timer.partialTicks); // Increase rendered frame this.frames++; @@ -203,9 +209,11 @@ export default class Minecraft { } } + // Render items in GUI + this.itemRenderer.render(partialTicks); + // Render current screen this.screenRenderer.render(partialTicks); - this.itemRenderer.render(partialTicks); } displayScreen(screen) { diff --git a/src/js/net/minecraft/client/gui/overlay/IngameOverlay.js b/src/js/net/minecraft/client/gui/overlay/IngameOverlay.js index 5b42614..d59c27e 100644 --- a/src/js/net/minecraft/client/gui/overlay/IngameOverlay.js +++ b/src/js/net/minecraft/client/gui/overlay/IngameOverlay.js @@ -36,7 +36,7 @@ export default class IngameOverlay extends Gui { // Render debug canvas on stack if (this.minecraft.settings.debugOverlay) { - stack.drawImage(this.window.canvas2d.debugCanvas, 0, 0); + stack.drawImage(this.window.canvasDebug, 0, 0); } } @@ -45,11 +45,11 @@ export default class IngameOverlay extends Gui { // Render debug overlay on tick if (this.minecraft.settings.debugOverlay) { - let stack = this.window.canvas2d.debugCanvas.getContext('2d'); - let moving = this.minecraft.player.isMoving(); + let stack = this.window.canvasDebug.getContext('2d'); + let fastUpdate = this.minecraft.player.isMoving() && this.minecraft.fps > 30; // Render debug overlay each tick if the player is moving - if (this.ticksRendered % (moving ? 1 : 20) === 0) { + if (this.ticksRendered % (fastUpdate ? 2 : 20) === 0) { // Clear debug canvas stack.clearRect(0, 0, this.window.width, this.window.height); diff --git a/src/js/net/minecraft/client/gui/screens/GuiMainMenu.js b/src/js/net/minecraft/client/gui/screens/GuiMainMenu.js index 35e6ebc..cf2336a 100644 --- a/src/js/net/minecraft/client/gui/screens/GuiMainMenu.js +++ b/src/js/net/minecraft/client/gui/screens/GuiMainMenu.js @@ -55,6 +55,7 @@ export default class GuiMainMenu extends GuiScreen { this.camera.rotation.x = -MathHelper.toRadians(rotationX + 180); this.camera.rotation.y = -MathHelper.toRadians(rotationY - 180); this.camera.updateProjectionMatrix(); + this.minecraft.worldRenderer.webRenderer.clear(); this.minecraft.worldRenderer.webRenderer.render(this.scene, this.camera); // Draw panorama overlay @@ -159,15 +160,17 @@ export default class GuiMainMenu extends GuiScreen { this.camera.rotation.order = 'ZYX'; // Apply blur - let style = this.minecraft.window.canvas2d.style; + let style = this.minecraft.window.canvas.style; style.backdropFilter = "blur(10px)"; style.webkitBackdropFilter = "blur(10px)"; + this.minecraft.window.wrapper.insertBefore(this.minecraft.window.canvasWorld, this.minecraft.window.canvas); } onClose() { // Remove blur - let style = this.minecraft.window.canvas2d.style; + let style = this.minecraft.window.canvas.style; style.backdropFilter = ""; style.webkitBackdropFilter = ""; + this.minecraft.window.wrapper.removeChild(this.minecraft.window.canvasWorld); } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/WorldRenderer.js b/src/js/net/minecraft/client/render/WorldRenderer.js index 4608fdc..ea3c0f1 100644 --- a/src/js/net/minecraft/client/render/WorldRenderer.js +++ b/src/js/net/minecraft/client/render/WorldRenderer.js @@ -77,7 +77,7 @@ export default class WorldRenderer { // Create web renderer this.webRenderer = new THREE.WebGLRenderer({ - canvas: this.window.canvas, + canvas: this.window.canvasWorld, antialias: false, alpha: true }); diff --git a/src/js/net/minecraft/client/render/gui/ItemRenderer.js b/src/js/net/minecraft/client/render/gui/ItemRenderer.js index b1e939a..0a4b29c 100644 --- a/src/js/net/minecraft/client/render/gui/ItemRenderer.js +++ b/src/js/net/minecraft/client/render/gui/ItemRenderer.js @@ -48,6 +48,7 @@ export default class ItemRenderer { this.camera.updateProjectionMatrix(); // Render scene + this.webRenderer.clear(); this.webRenderer.render(this.scene, this.camera); } @@ -115,18 +116,11 @@ export default class ItemRenderer { } destroy(groupId, renderId = null) { - let hit = false; - for (let i in this.items) { if (this.items[i].groupId === groupId && (renderId === null || this.items[i].renderId === renderId)) { this.scene.remove(this.items[i].group); delete this.items[i]; - hit = true; } } - - if (hit) { - this.webRenderer.clear(); - } } } \ No newline at end of file diff --git a/src/js/net/minecraft/client/render/gui/ScreenRenderer.js b/src/js/net/minecraft/client/render/gui/ScreenRenderer.js index 956d764..4e31962 100644 --- a/src/js/net/minecraft/client/render/gui/ScreenRenderer.js +++ b/src/js/net/minecraft/client/render/gui/ScreenRenderer.js @@ -4,18 +4,18 @@ export default class ScreenRenderer { this.minecraft = minecraft; this.window = window; - this.upscale = window.isMobileDevice() ? 1 : 3; + this.upscale = window.isMobileDevice() ? 1 : 4; } initialize() { this.resolution = this.minecraft.isInGame() ? 1 : this.minecraft.window.scaleFactor; // Increase resolution for the splash text // Update camera size - this.window.canvas2d.width = this.window.width * this.upscale; - this.window.canvas2d.height = this.window.height * this.upscale; + this.window.canvas.width = this.window.width * this.upscale; + this.window.canvas.height = this.window.height * this.upscale; // Get context stack of 2d canvas - this.stack2d = this.window.canvas2d.getContext('2d'); + this.stack2d = this.window.canvas.getContext('2d'); this.stack2d.webkitImageSmoothingEnabled = false; this.stack2d.mozImageSmoothingEnabled = false; this.stack2d.imageSmoothingEnabled = false; @@ -26,10 +26,16 @@ export default class ScreenRenderer { let mouseY = this.minecraft.window.mouseY; this.stack2d.save(); - this.stack2d.scale(this.upscale, this.upscale, this.upscale); - // Reset 2d canvas - this.stack2d.clearRect(0, 0, this.window.width, this.window.height); + // Draw world to canvas + if (this.minecraft.isInGame()) { + this.stack2d.drawImage(this.window.canvasWorld, 0, 0, this.window.width * this.upscale, this.window.height * this.upscale); + } else { + this.reset(); + } + + // Scale GUI + this.stack2d.scale(this.upscale, this.upscale, this.upscale); try { // Render in-game overlay @@ -45,11 +51,17 @@ export default class ScreenRenderer { console.error(e); } + // Scale GUI back + this.stack2d.scale(1 / this.upscale, 1 / this.upscale, 1 / this.upscale); + + // Render items + this.stack2d.drawImage(this.window.canvasItems, 0, 0); + this.stack2d.restore(); } reset() { - this.stack2d.clearRect(0, 0, this.window.canvas2d.width, this.window.canvas2d.height); + this.stack2d.clearRect(0, 0, this.window.canvas.width, this.window.canvas.height); } } \ No newline at end of file