import Engine from './engine' import Camera from './engine/camera' import loadMesh from './engine/mesh/loader' import { randomInt } from './engine/utility' import { Environment, Light } from './engine/environment' import { LODTerrain } from './engine/components/terrain/lod' import { MeshInstance } from './engine/components' import { Skybox } from './engine/components/skybox' import { WaterRenderer, WaterTile } from './engine/components/water' import { Particle, ParticleTexture, ParticleSystem, ParticleRenderer } from './engine/components/particles' import { SimplexHeightMap } from './engine/components/terrain/heightmap' import { Material, Texture } from './engine/mesh/material' import { GUIRenderer, GUIImage, Dim4 } from './engine/gui' import { FontRenderer, GUIText, Font } from './engine/gui/font' import { VoxelWorld, VoxelGenerator } from './engine/voxel' import { CubePlanet, PlanetGenerator, PlanetIndexBuffers } from './engine/components/planet' import Atmosphere from './engine/components/planet/atmosphere' const game = Engine const env = new Environment([0.1, 0.1, 0.1], new Light([0.0, 10000.0, -20000.0], [1.0, 1.0, 1.0])) const gui = new GUIRenderer() const fnt = new FontRenderer() const prt = new ParticleRenderer() async function pipeline () { const entity = await loadMesh(game.gl, 'test') const terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false) const skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false) const atmosShader = await game.shaders.createShaderFromFiles(game.gl, 'atmosphere', false) const planetShader = await game.shaders.createShaderFromFiles(game.gl, 'planet', false) entity.setRotation([0.0, 0.0, -90.0]) // Initialize water // let waterRenderer = new WaterRenderer() // let water = new WaterTile([100.0, 0.0, 100.0], 100.0) // await waterRenderer.initialize(game) // await waterRenderer.useDUDVMap(game.gl, 'dudv') // await waterRenderer.useNormalMap(game.gl, 'normalmap') const arialFont = await Font.fromFile('arial') await arialFont.loadTextures(game.gl) // Initialize GUI await gui.initialize(game) await fnt.initialize(game) // Initialize particles await prt.initialize(game) const particleSystem = new ParticleSystem(prt) // Particle texture atlas const particleTexture = new ParticleTexture(await Texture.fromFile(game.gl, 'particleAtlas.png'), 4) const itms = [ // new GUIImage(await Texture.fromFile(game.gl, 'noisy.png', false, game.gl.LINEAR), // new Dim4(-0.9, 0.0, 0.9, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0)) ] // Nesting test itms[0] = new GUIText('', arialFont, 0.8, new Dim4(0.0, 0.0, 0.0, 0.0), new Dim4(0.1, 0.0, 0.1, 0.0), false) itms[0].color = [0.0, 0.2, 1.0] // Create a height map based on OpenSimplex noise const hmap = new SimplexHeightMap(1, 20, 10, 0.2) // Create a terrain instance // let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4) // Terrain material const material = new Material(['grass-plain-1024.jpg']) await material.loadTextures(game.gl) // test code for (const i in entity.children) { entity.children[i].mesh.material = material } // Set generator and material for terrain // terrain.setGenerator(hmap) // terrain.setMaterial(material) // Create and initialize the camera // [-1300.0, 1325.0, -1300.0], [0.8, -0.6, 0.0] const cam = new Camera([0, 0, -2500], [1.5, -0, 0]) cam.updateProjection(game.gl) // Create skybox // const skybox = new Skybox('skybox', cam.farPlane / 2) // Load textures and generate a mesh // await skybox.initialize(game.gl) // Voxel test // let voxgen = new VoxelGenerator(hmap, material) // let block = new VoxelWorld(voxgen) // Planet test PlanetIndexBuffers.generate(15) const planet = new CubePlanet([0.0, 0.0, 0.0], new PlanetGenerator(1000, hmap)) const atmosphere = new Atmosphere(planet, 1050, [0.650, 0.570, 0.475]) planet.material = material // Update function for camera and terrain let fpsTimer = 0 game.addUpdateFunction(function (dt) { if (game.input.isDown('w')) { cam.processKeyboard(0, dt) } else if (game.input.isDown('s')) { cam.processKeyboard(1, dt) } if (game.input.isDown('a')) { cam.processKeyboard(2, dt) } else if (game.input.isDown('d')) { cam.processKeyboard(3, dt) } if (game.input.isPressed('c')) { console.log(cam.pos, cam.rotation) } // Panning if (game.input.mouseMoved && game.input.mouse.btn0) { cam.processMouseMove(game.input.mouseOffset) } // Particles particleSystem.update(dt, -50) if (game.input.isDown('y')) { const velocity = 20 for (let i = 0; i < 360; i += 15) { const rad1 = i * Math.PI / 180 const x1 = (Math.cos(rad1) * velocity) + randomInt(-5, 5) const y1 = (Math.sin(rad1) * velocity) + randomInt(-5, 5) particleSystem.add(new Particle(particleTexture, [0.0, 0.0, 0.0], [x1, randomInt(-velocity, velocity), y1], 0.2, 2, randomInt(0, 360), randomInt(0.1, 1))) } } // Update detail levels // terrain.update(game.gl, cam) // terrain.updateLODMesh(game.gl) // Ripple water // waterRenderer.update(dt) // Update voxel chunk // voxgen.update(dt) // block.update(game.gl, cam, dt) // Set text to FPS fpsTimer++ if (fpsTimer === 10) { itms[0].setText(game.fps + ' fps') fpsTimer = 0 } // Update planet LOD planet.update(cam, dt) }) function drawEverything (gl) { game.prepare() // Draw the skybox // skyboxShader.use(gl) // skybox.draw(gl, skyboxShader, cam) // Use terrain shader // terrainShader.use(gl) // Set environment variables in shader // env.draw(gl, terrainShader) // Set the viewport uniforms // cam.draw(gl, terrainShader) // Draw terrain // terrain.draw(gl, terrainShader) // entity.draw(gl, terrainShader) // block.draw(gl, terrainShader) CubePlanet.drawPlanetAtmosphere(gl, planet, atmosphere, cam, env.sun, atmosShader, planetShader, terrainShader, env) } // Render function for the triangle game.addRenderFunction(function (gl) { // waterRenderer.reflect(gl, cam, drawEverything) // waterRenderer.refract(gl, cam, drawEverything) drawEverything(gl) // waterRenderer.draw(gl, [water], cam, env.sun) // Draw particles particleSystem.draw(gl, cam) // Draw GUIs gui.draw(gl, cam, itms) fnt.draw(gl, cam, itms) }) game.startGameLoop() } // Start the game, catch any errors thrown pipeline().catch(function (e) { console.error(e) })