From 88db6b5e80a75f5123c350ad1d7bb4d0d875851d Mon Sep 17 00:00:00 2001 From: LabyStudio Date: Thu, 3 Feb 2022 12:41:29 +0100 Subject: [PATCH] improve gui rendering --- src/js/net/minecraft/client/GameWindow.js | 58 +++++----- src/js/net/minecraft/client/Minecraft.js | 4 +- .../net/minecraft/client/gui/IngameOverlay.js | 2 +- .../minecraft/client/render/WorldRenderer.js | 100 ++++++++++-------- 4 files changed, 89 insertions(+), 75 deletions(-) diff --git a/src/js/net/minecraft/client/GameWindow.js b/src/js/net/minecraft/client/GameWindow.js index 054c68b..744f1a8 100644 --- a/src/js/net/minecraft/client/GameWindow.js +++ b/src/js/net/minecraft/client/GameWindow.js @@ -1,36 +1,26 @@ window.GameWindow = class { - constructor(minecraft, renderer, canvasWrapperId) { - this.renderer = renderer; + constructor(minecraft, canvasWrapperId) { this.canvasWrapperId = canvasWrapperId; this.mouseMotionX = 0; this.mouseMotionY = 0; this.mouseLocked = false; - let wrapper = document.getElementById(this.canvasWrapperId); + this.wrapper = document.getElementById(this.canvasWrapperId); // Stats this.stats = new Stats() this.stats.showPanel(0); - wrapper.appendChild(this.stats.dom); + this.wrapper.appendChild(this.stats.dom); - // Add web renderer canvas to wrapper - let canvas = renderer.canvasElement; - wrapper.appendChild(canvas); - - // Init - this.onResize(); + // Initialize window size + this.updateWindowSize(); // On resize let scope = this; window.addEventListener('resize', _ => scope.onResize(), false); - // Request focus - canvas.onclick = function () { - canvas.requestPointerLock(); - } - // Focus listener document.addEventListener('pointerlockchange', _ => this.onFocusChanged(), false); @@ -44,25 +34,38 @@ window.GameWindow = class { Keyboard.create(); } + loadRenderer(renderer) { + this.renderer = renderer; + + let canvas = renderer.canvasElement; + + // Add web renderer canvas to wrapper + this.wrapper.appendChild(canvas); + + // Initialize window size + this.onResize(); + + // Request focus + canvas.onclick = function () { + canvas.requestPointerLock(); + } + } + + updateWindowSize() { + this.width = this.wrapper.offsetWidth; + this.height = this.wrapper.offsetHeight; + } + onResize() { - // Get canvas size - let canvasElement = document.getElementById(this.canvasWrapperId); - this.width = canvasElement.offsetWidth; - this.height = canvasElement.offsetHeight; + this.updateWindowSize(); // Adjust camera this.renderer.camera.aspect = this.width / this.height; this.renderer.camera.updateProjectionMatrix(); this.renderer.webRenderer.setSize(this.width, this.height); - // Update HUD camera - this.renderer.camera2D.left = -this.width / 2; - this.renderer.camera2D.right = this.width / 2; - this.renderer.camera2D.top = this.height / 2; - this.renderer.camera2D.bottom = -this.height / 2; - this.renderer.camera2D.updateProjectionMatrix(); - - console.log("Resize"); + // Reinitialize gui + this.renderer.initializeGui(); } onFocusChanged() { @@ -75,4 +78,5 @@ window.GameWindow = class { this.mouseX = event.clientX; this.mouseY = event.clientY; } + } \ No newline at end of file diff --git a/src/js/net/minecraft/client/Minecraft.js b/src/js/net/minecraft/client/Minecraft.js index 2fac032..f50aa1f 100644 --- a/src/js/net/minecraft/client/Minecraft.js +++ b/src/js/net/minecraft/client/Minecraft.js @@ -4,8 +4,8 @@ window.Minecraft = class { * Create Minecraft instance and render it on a canvas */ constructor(canvasWrapperId) { - this.worldRenderer = new WorldRenderer(this, canvasWrapperId); - this.window = new GameWindow(this, this.worldRenderer, canvasWrapperId); + this.window = new GameWindow(this, canvasWrapperId); + this.worldRenderer = new WorldRenderer(this, this.window); this.timer = new Timer(20); this.frames = 0; diff --git a/src/js/net/minecraft/client/gui/IngameOverlay.js b/src/js/net/minecraft/client/gui/IngameOverlay.js index 698648d..af2119a 100644 --- a/src/js/net/minecraft/client/gui/IngameOverlay.js +++ b/src/js/net/minecraft/client/gui/IngameOverlay.js @@ -1,7 +1,7 @@ window.IngameOverlay = class extends Gui { render(stack, mouseX, mouseY, partialTicks) { - this.drawRect(stack, 0, 0, 10, 10, '#0000FF'); + this.drawRect(stack, 0, 0, 500, 500, '#0000FF'); } } \ 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 5ec0a65..1e98505 100644 --- a/src/js/net/minecraft/client/render/WorldRenderer.js +++ b/src/js/net/minecraft/client/render/WorldRenderer.js @@ -2,22 +2,32 @@ window.WorldRenderer = class { static RENDER_DISTANCE = 4; - constructor(minecraft, canvasWrapperId) { + constructor(minecraft, window) { this.minecraft = minecraft; - - this.canvas2D = document.createElement('canvas'); - // Get canvas size - let canvasElement = document.getElementById(canvasWrapperId); - this.canvasWidth = canvasElement.offsetWidth; - this.canvasHeight = canvasElement.offsetHeight; - - this.stack2D = null; - this.hudTexture = null; + this.window = window; + this.chunkSectionUpdateQueue = []; this.supportWebGL = !!WebGLRenderingContext && (!!document.createElement('canvas').getContext('experimental-webgl') || !!document.createElement('canvas').getContext('webgl')); + // Load terrain + this.terrainTexture = new THREE.TextureLoader().load('src/resources/terrain.png'); + this.terrainTexture.magFilter = THREE.NearestFilter; + this.terrainTexture.minFilter = THREE.NearestFilter; + + // Block Renderer + this.blockRenderer = new BlockRenderer(this); + + // Initialize renderers + this.initializeRenderer(); + this.initializeGui(); + + // Load renderer into window + this.window.loadRenderer(this); + } + + initializeRenderer() { // Create world camera this.camera = new THREE.PerspectiveCamera(0, 1, 0.001, 1000); this.camera.rotation.order = 'ZYX'; @@ -41,49 +51,53 @@ window.WorldRenderer = class { }); // 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(); - - // Load terrain - this.terrainTexture = new THREE.TextureLoader().load('src/resources/terrain.png'); - this.terrainTexture.magFilter = THREE.NearestFilter; - this.terrainTexture.minFilter = THREE.NearestFilter; - - // Block Renderer - this.blockRenderer = new BlockRenderer(this); - - this.chunkSectionUpdateQueue = []; - - this.initializeHud(); } - initializeHud() { + initializeGui() { + // We will use 2D canvas element to render our HUD. + this.canvas2d = document.createElement('canvas') - // Create canvas context for screen rendering - this.stack2D = this.canvas2D.getContext('2d'); - this.hudTexture = new THREE.Texture(this.stack2D); - this.hudTexture.needsUpdate = true; + // Update camera size + this.canvas2d.width = this.window.width; + this.canvas2d.height = this.window.height; + + // Get context stack of 2d canvas + this.stack2d = this.canvas2d.getContext('2d'); + + // Create texture from rendered graphics. + this.frameBuffer = new THREE.Texture(this.canvas2d) + this.frameBuffer.needsUpdate = true; + this.frameBuffer.minFilter = THREE.LinearFilter; // Create HUD material. - let material = new THREE.MeshBasicMaterial({map: this.hudTexture}); - material.map.minFilter = THREE.LinearFilter; - material.transparent = true; + let material = new THREE.MeshBasicMaterial({ + map: this.frameBuffer, + transparent: true + }); // Create plane to render the HUD. This plane fill the whole screen. - let planeGeometry = new THREE.PlaneGeometry( this.canvas2D.width, this.canvas2D.height); - let plane = new THREE.Mesh(planeGeometry, material); + let geometry = new THREE.PlaneGeometry(this.canvas2d.width, this.canvas2d.height); + let plane = new THREE.Mesh(geometry, material); - // Create HUD - this.hud = new THREE.Scene(); - // this.hud.matrixAutoUpdate = false; - this.hud.add(plane); + // Create also a custom scene for HUD. + this.scene2d = new THREE.Scene(); + this.scene2d.add(plane); - // Create camera for HUD - this.camera2D = new THREE.OrthographicCamera(0, 0, 0, 0, 0, 30); + // Create 2D camera + this.camera2d = new THREE.OrthographicCamera(0, 0, 0, 0, 0, 30); + this.camera2d.aspect = this.window.width / this.window.height; + this.camera2d.left = -this.window.width / 2; + this.camera2d.right = this.window.width / 2; + this.camera2d.top = this.window.height / 2; + this.camera2d.bottom = -this.window.height / 2; + this.camera2d.updateProjectionMatrix(); } render(partialTicks) { @@ -99,15 +113,11 @@ window.WorldRenderer = class { // Render in-game overlay let mouseX = this.minecraft.window.mouseX; let mouseY = this.minecraft.window.mouseY; - //this.minecraft.ingameOverlay.render(this.stack2D, mouseX, mouseY, partialTicks); + this.minecraft.ingameOverlay.render(this.stack2d, mouseX, mouseY, partialTicks); - // Render actual scene + // Render actual scene and hud this.webRenderer.render(this.scene, this.camera); - - // Render actual HUD - if (this.stack2D !== null && this.hudTexture !== null && this.hudTexture.image.naturalWidth !== 0) { - this.webRenderer.render(this.hud, this.camera2D); - } + this.webRenderer.render(this.scene2d, this.camera2d); } orientCamera(partialTicks) {