Simple GUI, Simple Skybox, fixed sequential model rendering warnings
9
assets/shaders/skybox.fs
Normal file
@ -0,0 +1,9 @@
|
||||
precision mediump float;
|
||||
|
||||
varying vec3 uv;
|
||||
|
||||
uniform samplerCube cubeMap;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = textureCube(cubeMap, uv);
|
||||
}
|
13
assets/shaders/skybox.vs
Normal file
@ -0,0 +1,13 @@
|
||||
precision mediump float;
|
||||
|
||||
attribute vec3 aVertexPosition;
|
||||
|
||||
uniform mat4 uViewMatrix;
|
||||
uniform mat4 uProjectionMatrix;
|
||||
|
||||
varying vec3 uv;
|
||||
|
||||
void main() {
|
||||
gl_Position = uProjectionMatrix * uViewMatrix * vec4(aVertexPosition, 1.0);
|
||||
uv = aVertexPosition;
|
||||
}
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 46 KiB |
BIN
assets/textures/skybox/back.png
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
assets/textures/skybox/bottom.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/textures/skybox/front.png
Normal file
After Width: | Height: | Size: 991 KiB |
BIN
assets/textures/skybox/left.png
Normal file
After Width: | Height: | Size: 938 KiB |
BIN
assets/textures/skybox/right.png
Normal file
After Width: | Height: | Size: 1003 KiB |
BIN
assets/textures/skybox/top.png
Normal file
After Width: | Height: | Size: 342 KiB |
@ -23,6 +23,9 @@ class Camera extends Node {
|
||||
this.right = vec3.create()
|
||||
this.worldUp = vec3.fromValues(0.0, 1.0, 0.0)
|
||||
|
||||
this.nearPlane = ZNEAR
|
||||
this.farPlane = ZFAR
|
||||
|
||||
this.updateTransform()
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ class Camera extends Node {
|
||||
|
||||
updateProjection (gl) {
|
||||
let aspect = gl.canvas.width / gl.canvas.height
|
||||
mat4.perspective(this.projection, this.fov, aspect, ZNEAR, ZFAR)
|
||||
mat4.perspective(this.projection, this.fov, aspect, this.nearPlane, this.farPlane)
|
||||
}
|
||||
|
||||
// Calculate the view matrix on-the-go
|
||||
|
@ -224,6 +224,7 @@ class MeshInstance extends Node {
|
||||
// Draw the mesh
|
||||
this.mesh.prepare(gl, shader)
|
||||
this.mesh.draw(gl, shader)
|
||||
this.mesh.postdraw(gl, shader)
|
||||
|
||||
// Draw children
|
||||
super.draw(gl, shader)
|
||||
|
106
src/engine/components/skybox/index.js
Normal file
@ -0,0 +1,106 @@
|
||||
import { Mesh } from '../../mesh'
|
||||
import { Texture } from '../../mesh/material'
|
||||
|
||||
import { mat4 } from 'gl-matrix'
|
||||
|
||||
import Resource from '../../resource'
|
||||
|
||||
const FNAMES = ['right', 'left', 'top', 'bottom', 'back', 'front']
|
||||
const SIZE = 500
|
||||
|
||||
class Skybox {
|
||||
constructor (name, size = SIZE) {
|
||||
this.name = name
|
||||
this.size = size
|
||||
}
|
||||
|
||||
async initialize (gl) {
|
||||
await this.createTexture(gl)
|
||||
this.createMesh(gl)
|
||||
}
|
||||
|
||||
async createTexture (gl) {
|
||||
let ready = []
|
||||
for (let i in FNAMES) {
|
||||
let real = this.name + '/' + FNAMES[i] + '.png'
|
||||
let loaded = await Resource.loadImage(real)
|
||||
ready[i] = loaded
|
||||
}
|
||||
|
||||
let imgCube = Texture.createTextureCubeMap(gl, ready)
|
||||
this.cubemap = imgCube
|
||||
}
|
||||
|
||||
createMesh (gl) {
|
||||
const vertices = [
|
||||
-this.size, this.size, -this.size,
|
||||
-this.size, -this.size, -this.size,
|
||||
this.size, -this.size, -this.size,
|
||||
this.size, -this.size, -this.size,
|
||||
this.size, this.size, -this.size,
|
||||
-this.size, this.size, -this.size,
|
||||
|
||||
-this.size, -this.size, this.size,
|
||||
-this.size, -this.size, -this.size,
|
||||
-this.size, this.size, -this.size,
|
||||
-this.size, this.size, -this.size,
|
||||
-this.size, this.size, this.size,
|
||||
-this.size, -this.size, this.size,
|
||||
|
||||
this.size, -this.size, -this.size,
|
||||
this.size, -this.size, this.size,
|
||||
this.size, this.size, this.size,
|
||||
this.size, this.size, this.size,
|
||||
this.size, this.size, -this.size,
|
||||
this.size, -this.size, -this.size,
|
||||
|
||||
-this.size, -this.size, this.size,
|
||||
-this.size, this.size, this.size,
|
||||
this.size, this.size, this.size,
|
||||
this.size, this.size, this.size,
|
||||
this.size, -this.size, this.size,
|
||||
-this.size, -this.size, this.size,
|
||||
|
||||
-this.size, this.size, -this.size,
|
||||
this.size, this.size, -this.size,
|
||||
this.size, this.size, this.size,
|
||||
this.size, this.size, this.size,
|
||||
-this.size, this.size, this.size,
|
||||
-this.size, this.size, -this.size,
|
||||
|
||||
-this.size, -this.size, -this.size,
|
||||
-this.size, -this.size, this.size,
|
||||
this.size, -this.size, -this.size,
|
||||
this.size, -this.size, -this.size,
|
||||
-this.size, -this.size, this.size,
|
||||
this.size, -this.size, this.size
|
||||
]
|
||||
this.mesh = Mesh.constructFromVertices(gl, vertices)
|
||||
}
|
||||
|
||||
updateCamera (gl, shader, camera) {
|
||||
const projloc = shader.getUniformLocation(gl, 'uProjectionMatrix')
|
||||
const viewloc = shader.getUniformLocation(gl, 'uViewMatrix')
|
||||
|
||||
// Set translation to zero to prevent the skybox from moving in relation to the camera
|
||||
let view = mat4.clone(camera.view)
|
||||
view[12] = 0
|
||||
view[13] = 0
|
||||
view[14] = 0
|
||||
|
||||
gl.uniformMatrix4fv(projloc, false, camera.projection)
|
||||
gl.uniformMatrix4fv(viewloc, false, view)
|
||||
}
|
||||
|
||||
draw (gl, shader, camera) {
|
||||
camera && this.updateCamera(gl, shader, camera)
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0)
|
||||
gl.bindTexture(this.cubemap.type, this.cubemap.id)
|
||||
this.mesh.prepare(gl, shader)
|
||||
this.mesh.draw(gl, shader)
|
||||
this.mesh.postdraw(gl, shader)
|
||||
}
|
||||
}
|
||||
|
||||
export { Skybox }
|
@ -59,6 +59,7 @@ class Terrain extends Node {
|
||||
}
|
||||
|
||||
draw (gl, shader) {
|
||||
super.draw(gl, shader)
|
||||
if (!this.mesh) return
|
||||
// Set model transform matrix uniform
|
||||
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
|
||||
@ -66,8 +67,7 @@ class Terrain extends Node {
|
||||
|
||||
this.mesh.prepare(gl, shader)
|
||||
this.mesh.draw(gl, shader)
|
||||
|
||||
super.draw(gl, shader)
|
||||
this.mesh.postdraw(gl, shader)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,7 @@ class TerrainNode extends Node {
|
||||
|
||||
this.mesh.prepare(gl, shader)
|
||||
this.mesh.draw(gl, shader)
|
||||
this.mesh.postdraw(gl, shader)
|
||||
}
|
||||
|
||||
get generated () {
|
||||
|
@ -1,4 +1,25 @@
|
||||
import { clamp } from '../utility'
|
||||
import { Mesh } from '../mesh'
|
||||
import { mat4 } from 'gl-matrix'
|
||||
|
||||
const VERTEX_SHADER = `
|
||||
precision mediump float;
|
||||
attribute vec2 aVertexPosition;
|
||||
varying vec2 uv;
|
||||
uniform mat4 uTransformationMatrix;
|
||||
void main() {
|
||||
gl_Position = uTransformationMatrix * vec4(aVertexPosition, 0.0, 1.0);
|
||||
uv = vec2((aVertexPosition.x+1.0)/2.0, 1.0 - (aVertexPosition.y+1.0)/2.0);
|
||||
}
|
||||
`
|
||||
|
||||
const FRAGMENT_SHADER = `
|
||||
precision mediump float;
|
||||
varying vec2 uv;
|
||||
uniform sampler2D texture0;
|
||||
void main() {
|
||||
gl_FragColor = texture2D(texture0, uv);
|
||||
}
|
||||
`
|
||||
|
||||
class Dim4 {
|
||||
constructor (scX, ofX, scY, ofY) {
|
||||
@ -67,10 +88,34 @@ class Node2D {
|
||||
|
||||
this.parent = null
|
||||
this.children = []
|
||||
|
||||
this.transform = mat4.create()
|
||||
|
||||
this.updateTransform()
|
||||
}
|
||||
|
||||
updateTransform () {
|
||||
let matrix = mat4.create()
|
||||
mat4.translate(matrix, matrix, [this.pos[0], this.pos[2], 0.0])
|
||||
mat4.scale(matrix, matrix, [this.size[0], this.size[2], 1.0])
|
||||
if (this.rotation !== 0.0) {
|
||||
mat4.rotate(matrix, matrix, this.rotation * Math.PI / 180, [0.0, 0.0, 1.0])
|
||||
}
|
||||
|
||||
// Add parent's transform to this
|
||||
if (this.parent) {
|
||||
mat4.mul(matrix, this.parent.transform, matrix)
|
||||
}
|
||||
|
||||
// Set the matrix
|
||||
this.transform = matrix
|
||||
|
||||
// Update children's transforms
|
||||
for (let i in this.children) {
|
||||
let child = this.children[i]
|
||||
if (!(child instanceof Node2D)) continue
|
||||
child.updateTransform()
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
@ -83,12 +128,12 @@ class Node2D {
|
||||
}
|
||||
|
||||
// Draw base
|
||||
draw (gl) {
|
||||
draw (gl, shader, quad) {
|
||||
// Nothing to draw here, so just draw children
|
||||
for (let i in this.children) {
|
||||
let child = this.children[i]
|
||||
if (!(child instanceof Node2D)) continue
|
||||
child.draw(gl)
|
||||
child.draw(gl, shader, quad)
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,3 +163,55 @@ class Node2D {
|
||||
this.parent = p
|
||||
}
|
||||
}
|
||||
|
||||
class GUIImage extends Node2D {
|
||||
constructor (texture, pos, size, rotation) {
|
||||
super(pos, size, rotation)
|
||||
this.texture = texture
|
||||
this.active = true
|
||||
}
|
||||
|
||||
draw (gl, shader, quad) {
|
||||
super.draw(gl, shader, quad)
|
||||
if (!this.active) return
|
||||
gl.activeTexture(gl.TEXTURE0)
|
||||
gl.bindTexture(this.texture.type, this.texture.id)
|
||||
|
||||
// Set transformation matrix
|
||||
const transformLocation = shader.getUniformLocation(gl, 'uTransformationMatrix')
|
||||
gl.uniformMatrix4fv(transformLocation, false, this.transform)
|
||||
|
||||
// Draw the quad
|
||||
quad.draw(gl, shader, gl.TRIANGLE_STRIP)
|
||||
}
|
||||
}
|
||||
|
||||
class GUIRenderer {
|
||||
async initialize (game) {
|
||||
this.shader = await game.shaders.createShader(game.gl, 'gui', VERTEX_SHADER, FRAGMENT_SHADER)
|
||||
this.createQuad(game.gl)
|
||||
}
|
||||
|
||||
// Reusable quad mesh for rendering GUIs
|
||||
createQuad (gl) {
|
||||
if (this.quad) return this.quad
|
||||
this.quad = Mesh.constructFromVertices(gl, [-1, 1, -1, -1, 1, 1, 1, -1], 2)
|
||||
return this.quad
|
||||
}
|
||||
|
||||
draw (gl, nodes) {
|
||||
if (typeof nodes !== 'object') nodes = [ nodes ]
|
||||
this.shader.use(gl)
|
||||
this.quad.prepare(gl, this.shader)
|
||||
gl.enable(gl.BLEND)
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
|
||||
gl.disable(gl.DEPTH_TEST)
|
||||
for (let i in nodes) {
|
||||
nodes[i].draw(gl, this.shader, this.quad)
|
||||
}
|
||||
gl.enable(gl.DEPTH_TEST)
|
||||
gl.disable(gl.BLEND)
|
||||
}
|
||||
}
|
||||
|
||||
export { Dim4, GUIRenderer, GUIImage }
|
||||
|
@ -37,7 +37,7 @@ class Engine {
|
||||
|
||||
render () {
|
||||
// Set clear color to black, fully opaque
|
||||
gl.clearColor(0.0, 0.7, 1.0, 1.0)
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0)
|
||||
|
||||
// Clear the color buffer with specified clear color
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||
|
@ -38,21 +38,38 @@ class Mesh {
|
||||
return mesh
|
||||
}
|
||||
|
||||
static constructFromVertices (gl, vertices, dimensions = 3) {
|
||||
let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
|
||||
let mesh = new Mesh()
|
||||
mesh.posBuffer = pos
|
||||
mesh.vertices = vertices
|
||||
mesh.vertexCount = vertices.length / dimensions
|
||||
mesh.vertexLayout = dimensions
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null)
|
||||
|
||||
return mesh
|
||||
}
|
||||
|
||||
bindBuffers (gl, shader) {
|
||||
this._bufferCount = 1
|
||||
|
||||
let d = this.vertexLayout || 3
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer)
|
||||
shader.setAttribute(gl, 'aVertexPosition', 3, false, 3 * Float32Array.BYTES_PER_ELEMENT, 0)
|
||||
shader.setAttribute(gl, 'aVertexPosition', d, false, d * Float32Array.BYTES_PER_ELEMENT, 0)
|
||||
|
||||
if (this.nms && shader.hasAttribute(gl, 'aNormal')) {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.nms)
|
||||
shader.setAttribute(gl, 'aNormal', 3, false, 3 * Float32Array.BYTES_PER_ELEMENT, 0)
|
||||
this._bufferCount++
|
||||
}
|
||||
|
||||
if (this.uvs && shader.hasAttribute(gl, 'aTexCoords')) {
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvs)
|
||||
shader.setAttribute(gl, 'aTexCoords', 2, false, 2 * Float32Array.BYTES_PER_ELEMENT, 0)
|
||||
this._bufferCount++
|
||||
}
|
||||
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ebo)
|
||||
this.ebo && gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.ebo)
|
||||
}
|
||||
|
||||
prepare (gl, shader) {
|
||||
@ -69,7 +86,14 @@ class Mesh {
|
||||
if (this.indices) {
|
||||
gl.drawElements(mode, this.indices.length, gl.UNSIGNED_SHORT, 0)
|
||||
} else {
|
||||
gl.drawArrays(mode, 0, this.vertices.length)
|
||||
gl.drawArrays(mode, 0, this.vertexCount || this.vertices.length / (this.vertexLayout || 3))
|
||||
}
|
||||
}
|
||||
|
||||
// Unbind all attrib arrays after drawing something
|
||||
postdraw (gl, shader) {
|
||||
for (let i = 0; i < this._bufferCount; i++) {
|
||||
gl.disableVertexAttribArray(i)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,22 @@
|
||||
import Resource from '../resource'
|
||||
|
||||
class Texture {
|
||||
static createTexture2D (gl, img) {
|
||||
static createTexture2D (gl, img, flip = true, filtering, repeat = gl.REPEAT) {
|
||||
let tex = gl.createTexture()
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex)
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip)
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img)
|
||||
|
||||
gl.generateMipmap(gl.TEXTURE_2D)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, repeat)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, repeat)
|
||||
|
||||
if (filtering) {
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filtering)
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filtering)
|
||||
} else {
|
||||
gl.generateMipmap(gl.TEXTURE_2D)
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null)
|
||||
|
||||
let oTex = new Texture()
|
||||
@ -16,9 +25,39 @@ class Texture {
|
||||
|
||||
return oTex
|
||||
}
|
||||
|
||||
static createTextureCubeMap (gl, img) {
|
||||
if (!img || img.length !== 6) throw new Error('createTextureCubeMap() requires six images!')
|
||||
let tex = gl.createTexture()
|
||||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex)
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false)
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[0])
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[1])
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[2])
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[3])
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[4])
|
||||
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[5])
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null)
|
||||
|
||||
let oTex = new Texture()
|
||||
oTex.type = gl.TEXTURE_CUBE_MAP
|
||||
oTex.id = tex
|
||||
|
||||
return oTex
|
||||
}
|
||||
}
|
||||
|
||||
class Material {
|
||||
constructor (textures) {
|
||||
this.textures = textures
|
||||
}
|
||||
|
||||
async loadTextures (gl) {
|
||||
if (this.textures) {
|
||||
for (let ti in this.textures) {
|
||||
|
@ -4,7 +4,7 @@ class Screen {
|
||||
constructor () {
|
||||
this._el = document.createElement('canvas')
|
||||
this.resize()
|
||||
this._gl = this._el.getContext('webgl')
|
||||
this._gl = this._el.getContext('webgl', { alpha: false })
|
||||
|
||||
if (!this._gl) {
|
||||
alert('Your machine or browser does not support WebGL!')
|
||||
|
46
src/index.js
@ -1,34 +1,50 @@
|
||||
import Engine from './engine'
|
||||
import Camera from './engine/camera'
|
||||
import Resource from './engine/resource'
|
||||
import loadMesh from './engine/mesh/loader'
|
||||
|
||||
import { Environment } from './engine/environment'
|
||||
import { LODTerrain } from './engine/components/terrain/lod'
|
||||
import { Skybox } from './engine/components/skybox'
|
||||
import { SimplexHeightMap } from './engine/components/terrain/heightmap'
|
||||
import { Material } from './engine/mesh/material'
|
||||
import { Material, Texture } from './engine/mesh/material'
|
||||
import { GUIRenderer, GUIImage, Dim4 } from './engine/gui'
|
||||
|
||||
let game = new Engine()
|
||||
let env = new Environment()
|
||||
let gui = new GUIRenderer()
|
||||
|
||||
// let t = 0
|
||||
async function pipeline () {
|
||||
let entity = await loadMesh(game.gl, 'test')
|
||||
let shader = await game.shaders.createShaderFromFiles(game.gl, 'basic', false)
|
||||
let terrainShader = await game.shaders.createShaderFromFiles(game.gl, 'terrain', false)
|
||||
let skyboxShader = await game.shaders.createShaderFromFiles(game.gl, 'skybox', false)
|
||||
|
||||
entity.setRotation([0.0, 0.0, -90.0])
|
||||
|
||||
// Initialize GUI
|
||||
await gui.initialize(game)
|
||||
let itms = [
|
||||
new GUIImage(await Texture.createTexture2D(game.gl, await Resource.loadImage('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))
|
||||
]
|
||||
|
||||
// Create a height map based on OpenSimplex noise
|
||||
let hmap = new SimplexHeightMap(1, 1, 256, 50)
|
||||
|
||||
// Create a terrain
|
||||
// Create a terrain instance
|
||||
let terrain = new LODTerrain([0.0, 0.0, 0.0], 1024, 1024, 850, 4)
|
||||
|
||||
// Terrain material
|
||||
let material = new Material()
|
||||
material.textures = ['grass-1024.jpg']
|
||||
let material = new Material(['grass-1024.jpg'])
|
||||
await material.loadTextures(game.gl)
|
||||
|
||||
// test code
|
||||
for (let i in entity.children) {
|
||||
entity.children[i].mesh.material = material
|
||||
}
|
||||
|
||||
// Set generator and material for terrain
|
||||
terrain.setGenerator(hmap)
|
||||
terrain.setMaterial(material)
|
||||
|
||||
@ -36,7 +52,13 @@ async function pipeline () {
|
||||
let cam = new Camera([-200.0, 1.0, 0.0])
|
||||
cam.updateProjection(game.gl)
|
||||
|
||||
// Update function for camera
|
||||
// Create skybox
|
||||
let skybox = new Skybox('skybox', cam.farPlane / 2)
|
||||
|
||||
// Load textures and generate a mesh
|
||||
await skybox.initialize(game.gl)
|
||||
|
||||
// Update function for camera and terrain
|
||||
game.addUpdateFunction(function (dt) {
|
||||
if (game.input.isDown('w')) {
|
||||
cam.processKeyboard(0, dt)
|
||||
@ -50,6 +72,7 @@ async function pipeline () {
|
||||
cam.processKeyboard(3, dt)
|
||||
}
|
||||
|
||||
// Panning
|
||||
if (game.input.mouseMoved && game.input.mouse.btn0) {
|
||||
cam.processMouseMove(game.input.mouseOffset)
|
||||
}
|
||||
@ -57,10 +80,6 @@ async function pipeline () {
|
||||
// Update detail levels
|
||||
terrain.update(game.gl, cam)
|
||||
terrain.updateLODMesh(game.gl)
|
||||
|
||||
// TESTING: Move model forward
|
||||
// t = t + 0.1
|
||||
// entity.setPosition([t, 0.0, 0.0])
|
||||
})
|
||||
|
||||
// Render function for the triangle
|
||||
@ -80,6 +99,13 @@ async function pipeline () {
|
||||
|
||||
// Draw terrain
|
||||
terrain.draw(gl, terrainShader)
|
||||
// Draw the skybox
|
||||
skyboxShader.use(gl)
|
||||
skybox.draw(gl, skyboxShader, cam)
|
||||
})
|
||||
|
||||
game.addRenderFunction(function (gl) {
|
||||
gui.draw(gl, itms)
|
||||
})
|
||||
|
||||
game.startGameLoop()
|
||||
|