broken planet

This commit is contained in:
Evert Prants 2019-02-26 14:02:12 +02:00
parent c785db574c
commit befbcc5480
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
15 changed files with 514 additions and 69 deletions

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"/> <meta charset="utf-8"/>
<style type="text/css">*{margin:0;padding:0;}body{width:100%;height:100%;}body,html{overflow:hidden;}</style> <style type="text/css">*{margin:0;padding:0;}body{width:100%;height:100%;}body,html{overflow:hidden;}</style>
<title>Trotland</title> <title>3D Experiments</title>
</head> </head>
<body> <body>
</body> </body>

View File

@ -1,7 +1,7 @@
{ {
"name": "trotland-game", "name": "3dexperiments",
"version": "0.0.1", "version": "0.0.1",
"description": "Trotland 3D MMORPG", "description": "3D Experiments",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"serve": "node ./serve.js", "serve": "node ./serve.js",
@ -9,7 +9,7 @@
"watch": "webpack -w --mode=development" "watch": "webpack -w --mode=development"
}, },
"keywords": [ "keywords": [
"game", "experiment",
"webgl" "webgl"
], ],
"private": true, "private": true,

View File

@ -1,11 +1,11 @@
import { Node } from './components' import { Node } from './components'
import { glMatrix, mat4, vec2, vec3 } from 'gl-matrix' import { glMatrix, mat4, vec2, vec3 } from 'gl-matrix'
const SPEED = 10.0 const SPEED = 100.0
const SENSITIVTY = 100.0 const SENSITIVTY = 100.0
const FOV = 45.0 const FOV = 45.0
const ZNEAR = 0.1 const ZNEAR = 0.1
const ZFAR = 1000.0 const ZFAR = 10000.0
class Camera extends Node { class Camera extends Node {
constructor (pos, rotation) { constructor (pos, rotation) {

View File

@ -47,6 +47,7 @@ class Node {
this.rotation = rotation || [0.0, 0.0, 0.0] this.rotation = rotation || [0.0, 0.0, 0.0]
this.transform = mat4.create() this.transform = mat4.create()
this.updateTransform() this.updateTransform()
this.parent = null this.parent = null
@ -63,8 +64,8 @@ class Node {
// Add local transform to the global transform, if present // Add local transform to the global transform, if present
// Will be present in loaded models // Will be present in loaded models
if (this._rootTransform) { if (this.worldTransform) {
mat4.mul(matrix, matrix, this._rootTransform) mat4.mul(matrix, matrix, this.worldTransform)
} }
// Add parent's transform to this // Add parent's transform to this
@ -158,13 +159,33 @@ class Node {
// Draw base // Draw base
draw (gl, shader) { draw (gl, shader) {
// Set model transform matrix uniform // Nothing to draw here, so just draw children
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix') for (let i in this.children) {
gl.uniformMatrix4fv(transformLocation, false, this.transform) let child = this.children[i]
if (!(child instanceof Node)) continue
child.draw(gl, shader)
}
}
update (dt) {
// Update children
for (let i in this.children) {
let child = this.children[i]
if (!(child instanceof Node)) continue
child.update(dt)
}
} }
addChild (ch) { addChild (ch) {
// Recursive add in case of table
if (ch && typeof ch === 'object' && ch.length) {
for (let i in ch) {
this.addChild(ch[i])
}
}
if (!(ch instanceof Node)) return if (!(ch instanceof Node)) return
ch.setParent(this)
this.children.push(ch) this.children.push(ch)
this.updateTransform() this.updateTransform()
} }
@ -184,41 +205,18 @@ class MeshInstance extends Node {
} }
draw (gl, shader) { draw (gl, shader) {
// Set model transform uniform if (!this.mesh) return super.draw(gl, shader)
super.draw(gl, shader) // Set model transform matrix uniform
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLocation, false, this.transform)
// Draw the mesh // Draw the mesh
this.mesh.prepare(gl, shader) this.mesh.prepare(gl, shader)
this.mesh.draw(gl, shader) this.mesh.draw(gl, shader)
// Invoke children's draw methods // Draw children
for (let i in this.children) { super.draw(gl, shader)
let child = this.children[i]
if (!(child instanceof MeshInstance)) continue
child.draw(gl, shader)
}
} }
} }
// A node that contains multiple meshes export { Node, MeshInstance }
class MultiMeshInstance extends Node {
constructor (meshes, pos) {
super(pos)
for (let i in meshes) {
meshes[i].parent = this
this.children.push(meshes[i])
}
}
draw (gl, shader) {
// Invoke children's draw methods
for (let i in this.children) {
let child = this.children[i]
if (!(child instanceof MeshInstance)) continue
child.draw(gl, shader)
}
}
}
export { Node, MeshInstance, MultiMeshInstance }

View File

@ -0,0 +1,124 @@
import { Mesh } from '../../mesh'
import { mat4 } from 'gl-matrix'
import { subv3, mulv3, addv3, normalv3, crossv3 } from '../../utility'
class CubeFace {
constructor (parent, level, pos, normal, resolution, radius, generator) {
this.parent = parent
this.children = []
this.position = pos
this.normal = normal
this.resolution = resolution
this.radius = radius
this.level = 0
this.generated = false
// Calculate left and forward vectors from the normal
this.left = [normal[1], normal[2], normal[0]]
this.forward = crossv3(normal, this.left)
this.transform = mat4.create()
mat4.fromTranslation(this.transform, this.position)
this.generate()
}
generate () {
if (this.generated) return
let cpoint = subv3(this.position, mulv3(this.left, this.radius / 2))
cpoint = subv3(cpoint, mulv3(this.forward, this.radius / 2))
let VERTICES = this.resolution
let count = VERTICES * VERTICES
let vertices = new Array(count * 3)
// let normals = new Array(count * 3)
let textureCoords = new Array(count * 2)
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
for (let i = 0, vertexPointer = 0; i < VERTICES; i++) {
for (let j = 0; j < VERTICES; j++, vertexPointer++) {
let isize = i / VERTICES * this.radius
let jsize = j / VERTICES * this.radius
// From the left and forward vectors, we can calculate an oriented vertex
let iv = mulv3(this.left, isize)
let jv = mulv3(this.forward, jsize)
// Add the scaled left and forward to the centered origin
let vertex = addv3(cpoint.slice(0), addv3(iv, jv))
// Normalize and multiply by radius to create a spherical mesh
let pos = mulv3(normalv3(vertex), this.radius)
vertices[vertexPointer * 3] = pos[0]
vertices[vertexPointer * 3 + 1] = pos[1]
vertices[vertexPointer * 3 + 2] = pos[2]
// normals[vertexPointer * 3] = normal[0]
// normals[vertexPointer * 3 + 1] = normal[1]
// normals[vertexPointer * 3 + 2] = normal[2]
textureCoords[vertexPointer * 2] = j / (VERTICES - 1)
textureCoords[vertexPointer * 2 + 1] = i / (VERTICES - 1)
}
}
for (let gz = 0, pointer = 0; gz < VERTICES - 1; gz++) {
for (let gx = 0; gx < VERTICES - 1; gx++) {
let topLeft = (gz * VERTICES) + gx
let topRight = topLeft + 1
let bottomLeft = ((gz + 1) * VERTICES) + gx
let bottomRight = bottomLeft + 1
indices[pointer++] = topLeft
indices[pointer++] = bottomLeft
indices[pointer++] = topRight
indices[pointer++] = topRight
indices[pointer++] = bottomLeft
indices[pointer++] = bottomRight
}
}
this.mesh = Mesh.construct(window.gl, vertices, indices, textureCoords)
this.generated = true
}
draw (gl, shader) {
// Set model transform matrix uniform
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLocation, false, this.transform)
this.mesh.prepare(gl, shader)
this.mesh.draw(gl, shader)
}
}
class CubePlanet {
constructor (origin, resolution, radius, generator) {
this.origin = origin
this.resolution = resolution
this.radius = radius
let hs = resolution / 2
this.faces = [
new CubeFace(this, 0, [0, 0, -hs], [0, 0, -1], resolution, radius, generator), // front
// new CubeFace(this, 0, [0, 0, hs], [0, 0, 1], resolution, radius, generator), // back
new CubeFace(this, 0, [-hs, 0, 0], [-1, 0, 0], resolution, radius, generator), // left
// new CubeFace(this, 0, [hs, 0, 0], [1, 0, 0], resolution, radius, generator), // right
// new CubeFace(this, 0, [0, hs, 0], [0, 1, 0], resolution, radius, generator), // top
// new CubeFace(this, 0, [0, -hs, 0], [0, -1, 0], resolution, radius, generator) // bottom
]
}
draw (gl, shader) {
for (let i in this.faces) {
this.faces[i].draw(gl, shader)
}
}
}
export { CubePlanet, CubeFace }

View File

@ -0,0 +1,96 @@
import { Node } from '../'
import { Mesh } from '../../mesh'
import { vec3 } from 'gl-matrix'
import { subv3, mulv3, addv3, normalv3 } from '../../utility'
class Terrain extends Node {
constructor (pos, sWidth, sHeight, face = [0.0, -1.0, 0.0]) {
super(pos)
this.width = sWidth
this.height = sHeight
this.mesh = null
// Calculate left and forward vectors
this.left = [face[1], face[2], face[0]] || [1.0, 0.0, 0.0]
this.forward = [0.0, 0.0, -1.0]
vec3.cross(this.forward, face, this.left)
}
createMesh (gl, heightMap) {
// Center the mesh
let cpoint = [0.0, 0.0, 0.0]
cpoint = subv3(cpoint, mulv3(this.left, heightMap.size / 2))
cpoint = subv3(cpoint, mulv3(this.forward, heightMap.size / 2))
let VERTICES = heightMap.size
let count = VERTICES * VERTICES
let vertices = new Array(count * 3)
let normals = new Array(count * 3)
let textureCoords = new Array(count * 2)
let indices = new Array(6 * (VERTICES - 1) * (VERTICES - 1))
let vertexPointer = 0
for (let i = 0; i < VERTICES; i++) {
for (let j = 0; j < VERTICES; j++) {
let isize = j / (VERTICES - 1) * this.width / 2
let jsize = i / (VERTICES - 1) * this.height / 2
// From the left and forward vectors, we can calculate an oriented vertex
let iv = mulv3(this.left, isize)
let jv = mulv3(this.forward, jsize)
// Add the scaled left and forward to the centered origin
let pos = addv3(cpoint.slice(0), addv3(iv, jv))
vertices[vertexPointer * 3] = pos[0]
vertices[vertexPointer * 3 + 1] = pos[1]
vertices[vertexPointer * 3 + 2] = pos[2]
let normal = [0.0, 1.0, 0.0] // heightMap.getNormal(j, i)
normals[vertexPointer * 3] = normal[0]
normals[vertexPointer * 3 + 1] = normal[1]
normals[vertexPointer * 3 + 2] = normal[2]
textureCoords[vertexPointer * 2] = j / (VERTICES - 1)
textureCoords[vertexPointer * 2 + 1] = i / (VERTICES - 1)
vertexPointer++
}
}
let pointer = 0
for (let gz = 0; gz < VERTICES - 1; gz++) {
for (let gx = 0; gx < VERTICES - 1; gx++) {
let topLeft = (gz * VERTICES) + gx
let topRight = topLeft + 1
let bottomLeft = ((gz + 1) * VERTICES) + gx
let bottomRight = bottomLeft + 1
indices[pointer++] = topLeft
indices[pointer++] = bottomLeft
indices[pointer++] = topRight
indices[pointer++] = topRight
indices[pointer++] = bottomLeft
indices[pointer++] = bottomRight
}
}
this.mesh = Mesh.construct(gl, vertices, indices, textureCoords, normals)
}
setMaterial (mat) {
this.mesh.material = mat
}
draw (gl, shader) {
if (!this.mesh) return
// Set model transform matrix uniform
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLocation, false, this.transform)
this.mesh.prepare(gl, shader)
this.mesh.draw(gl, shader)
super.draw(gl, shader)
}
}
export { Terrain }

View File

@ -60,10 +60,14 @@ class Terrain extends Node {
draw (gl, shader) { draw (gl, shader) {
if (!this.mesh) return if (!this.mesh) return
super.draw(gl, shader) // Set model transform matrix uniform
const transformLocation = shader.getUniformLocation(gl, 'uModelMatrix')
gl.uniformMatrix4fv(transformLocation, false, this.transform)
this.mesh.prepare(gl, shader) this.mesh.prepare(gl, shader)
this.mesh.draw(gl, shader) this.mesh.draw(gl, shader)
super.draw(gl, shader)
} }
} }

120
src/engine/gui/index.js Normal file
View File

@ -0,0 +1,120 @@
import { clamp } from '../utility'
class Dim4 {
constructor (scX, ofX, scY, ofY) {
this.scX = scX
this.ofX = ofX
this.scY = scY
this.ofY = ofY
this._update()
}
static fromTable (tbl) {
let sx = 0.0
let ox = 0.0
let sy = 0.0
let oy = 0.0
if (tbl.length === 2) {
let x = tbl[0]
let y = tbl[1]
if (typeof x === 'object' && x.length === 2) {
sx = x[0]
ox = x[1]
} else if (typeof x === 'number') {
sx = x
}
if (typeof y === 'object' && y.length === 2) {
sx = y[0]
ox = y[1]
} else if (typeof y === 'number') {
sx = y
}
} else if (tbl.length === 4) {
sx = tbl[0]
ox = tbl[1]
sy = tbl[2]
oy = tbl[3]
}
return new Dim4(sx, ox, sy, oy)
}
toTable () {
return [this.scX, this.ofX, this.scY, this.ofY]
}
_update () {
this[0] = this.scX
this[1] = this.ofX
this[2] = this.scY
this[3] = this.ofY
}
}
class Node2D {
constructor (pos, size, rotation) {
// Translation
this.gpos = [0.0, 0.0]
this.pos = pos || new Dim4(0.0, 0.0, 0.0, 0.0)
// Scaling
this.gscale = [1.0, 1.0]
this.size = size || new Dim4(0.0, 0.0, 0.0, 0.0)
// Rotation in degrees
this.rotation = rotation || 0.0
this.parent = null
this.children = []
}
updateTransform () {
}
// Getters
get position () {
return this.pos
}
get translation () {
return this.pos
}
// Draw base
draw (gl) {
// 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)
}
}
update (dt) {
// Update children
for (let i in this.children) {
let child = this.children[i]
if (!(child instanceof Node2D)) continue
child.update(dt)
}
}
addChild (ch) {
// Recursive add in case of table
if (ch && typeof ch === 'object' && ch.length) {
for (let i in ch) {
this.addChild(ch[i])
}
}
if (!(ch instanceof Node2D)) return
this.children.push(ch)
}
setParent (p) {
if (!(p instanceof Node2D)) return
this.parent = p
}
}

View File

View File

@ -17,6 +17,8 @@ class Engine {
this.frameTime = 0 this.frameTime = 0
this.frameCount = 0 this.frameCount = 0
this.fps = 0 this.fps = 0
window.gl = this.screen.gl
} }
get gl () { get gl () {

View File

@ -1,35 +1,36 @@
class Mesh { class Mesh {
static loadToBuffer (gl, type, data, drawtype = gl.STATIC_DRAW) {
let id = gl.createBuffer()
gl.bindBuffer(type, id)
gl.bufferData(type, data, drawtype)
return id
}
static construct (gl, vertices, indices, uvs, normals) { static construct (gl, vertices, indices, uvs, normals) {
// VBO for model vertices // VBO for model vertices
let pos = gl.createBuffer() let pos = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(vertices))
gl.bindBuffer(gl.ARRAY_BUFFER, pos)
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
// Indices Buffer // Indices Buffer
let ebo = gl.createBuffer() let ebo = Mesh.loadToBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices))
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW)
// Create the mesh, as we have the most important data already buffered
let mesh = new Mesh() let mesh = new Mesh()
mesh.posBuffer = pos mesh.posBuffer = pos
mesh.ebo = ebo mesh.ebo = ebo
mesh.indices = indices.length mesh.vertices = vertices
mesh.indices = indices
// VBO for model UVs // VBO for model UVs
if (uvs) { if (uvs) {
let uv = gl.createBuffer() mesh.uv = uvs
gl.bindBuffer(gl.ARRAY_BUFFER, uv) mesh.uvs = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(uvs))
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uvs), gl.STATIC_DRAW)
mesh.uvs = uv
} }
// Normals buffer // Normals buffer
if (normals) { if (normals) {
let nms = gl.createBuffer() mesh.normals = normals
gl.bindBuffer(gl.ARRAY_BUFFER, nms) mesh.nms = Mesh.loadToBuffer(gl, gl.ARRAY_BUFFER, new Float32Array(normals))
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW)
mesh.nms = nms
} }
gl.bindBuffer(gl.ARRAY_BUFFER, null) gl.bindBuffer(gl.ARRAY_BUFFER, null)
@ -64,8 +65,31 @@ class Mesh {
} }
} }
draw (gl, shader) { draw (gl, shader, mode = gl.TRIANGLES) {
gl.drawElements(gl.TRIANGLES, this.indices, gl.UNSIGNED_SHORT, 0) if (this.indices) {
gl.drawElements(mode, this.indices.length, gl.UNSIGNED_SHORT, 0)
} else {
gl.drawArrays(mode, 0, this.vertices.length)
}
}
// Make sure no data floats around in memory
dispose (gl) {
gl.deleteBuffer(this.posBuffer)
gl.deleteBuffer(this.ebo)
this.uvs && gl.deleteBuffer(this.uvs)
this.nms && gl.deleteBuffer(this.nms)
this.vertices = null
this.indices = null
this.uv = null
this.normals = null
}
recreate (gl) {
let msh = Mesh.construct(gl, this.vertices, this.indices, this.uv, this.normals)
if (!msh) return null
this.dispose(gl)
return msh
} }
} }

View File

@ -1,5 +1,5 @@
import { Mesh } from './' import { Mesh } from './'
import { MeshInstance, MultiMeshInstance } from '../components' import { Node, MeshInstance } from '../components'
import { Material } from './material' import { Material } from './material'
import { mat4 } from 'gl-matrix' import { mat4 } from 'gl-matrix'
@ -122,7 +122,7 @@ async function assimp2json (gl, file, dat) {
} }
mat4.transpose(transform, transform) mat4.transpose(transform, transform)
meshInstance._rootTransform = transform meshInstance.worldTransform = transform
meshInstance.updateTransform() meshInstance.updateTransform()
} }
@ -135,9 +135,10 @@ async function assimp2json (gl, file, dat) {
let returnType let returnType
if (finished.length > 1) { if (finished.length > 1) {
returnType = new MultiMeshInstance(finished) returnType = new Node()
returnType.addChild(finished)
mat4.transpose(lastTransform, lastTransform) mat4.transpose(lastTransform, lastTransform)
returnType._rootTransform = lastTransform returnType.worldTransform = lastTransform
returnType.updateTransform() returnType.updateTransform()
} else { } else {
returnType = finished[0] returnType = finished[0]
@ -155,7 +156,12 @@ async function loadMesh (gl, file) {
file = '/assets/models/' + file + '.json' file = '/assets/models/' + file + '.json'
// Ensure each mesh file is loaded only once // Ensure each mesh file is loaded only once
if (meshCache[file]) return meshCache[file].length > 1 ? new MultiMeshInstance(meshCache[file]) : meshCache[file][0] if (meshCache[file]) {
if (meshCache[file].length <= 1) return meshCache[file][0]
let cached = new Node()
cached.addChild(meshCache[file])
return cached
}
let dat = await Resource.GET({ type: 'json', url: file }) let dat = await Resource.GET({ type: 'json', url: file })

View File

@ -40,8 +40,8 @@ class Material {
for (let i in this.textures) { for (let i in this.textures) {
let tex = this.textures[i] let tex = this.textures[i]
if (tex && tex instanceof Texture) { if (tex && tex instanceof Texture) {
gl.bindTexture(tex.type, tex.id)
gl.activeTexture(gl.TEXTURE0 + parseInt(i)) gl.activeTexture(gl.TEXTURE0 + parseInt(i))
gl.bindTexture(tex.type, tex.id)
} }
} }
} }

65
src/engine/utility.js Normal file
View File

@ -0,0 +1,65 @@
import { vec3 } from 'gl-matrix'
export function clamp (num, min, max) {
return Math.min(Math.max(num, min), max)
}
export function addv3 (one, two) {
if (one.length !== 3) return null
if (typeof two !== 'object') {
return [
one[0] + two, one[1] + two, one[2] + two
]
}
return [
one[0] + two[0], one[1] + two[1], one[2] + two[2]
]
}
export function subv3 (one, two) {
if (one.length !== 3) return null
if (typeof two !== 'object') {
return [
one[0] - two, one[1] - two, one[2] - two
]
}
return [
one[0] - two[0], one[1] - two[1], one[2] - two[2]
]
}
export function mulv3 (one, two) {
if (one.length !== 3) return null
if (typeof two !== 'object') {
return [
one[0] * two, one[1] * two, one[2] * two
]
}
return [
one[0] * two[0], one[1] * two[1], one[2] * two[2]
]
}
export function divv3 (one, two) {
if (one.length !== 3) return null
if (typeof two !== 'object') {
return [
one[0] / two, one[1] / two, one[2] / two
]
}
return [
one[0] / two[0], one[1] / two[1], one[2] / two[2]
]
}
export function normalv3 (vec) {
let res = []
vec3.normalize(res, vec)
return res
}
export function crossv3 (vec1, vec2) {
let res = []
vec3.cross(res, vec1, vec2)
return res
}

View File

@ -7,10 +7,12 @@ import { Terrain } from './engine/components/terrain'
import { SimplexHeightMap } from './engine/components/terrain/heightmap' import { SimplexHeightMap } from './engine/components/terrain/heightmap'
import { Material } from './engine/mesh/material' import { Material } from './engine/mesh/material'
import { CubePlanet } from './engine/components/planet'
let game = new Engine() let game = new Engine()
let env = new Environment() let env = new Environment()
let t = 0 // let t = 0
async function pipeline () { async function pipeline () {
let entity = await loadMesh(game.gl, 'test') let entity = await loadMesh(game.gl, 'test')
let shader = await game.shaders.createShaderFromFiles(game.gl, 'basic', false) let shader = await game.shaders.createShaderFromFiles(game.gl, 'basic', false)
@ -32,9 +34,12 @@ async function pipeline () {
terrain.setMaterial(material) terrain.setMaterial(material)
// Create and initialize the camera // Create and initialize the camera
let cam = new Camera([0.0, 1.0, 2.0]) let cam = new Camera([-100.0, 1.0, 0.0])
cam.updateProjection(game.gl) cam.updateProjection(game.gl)
// Planet test
let planet = new CubePlanet([0.0, 0.0, 0.0], 16, 32)
// Update function for camera // Update function for camera
game.addUpdateFunction(function (dt) { game.addUpdateFunction(function (dt) {
if (game.input.isDown('w')) { if (game.input.isDown('w')) {
@ -54,8 +59,8 @@ async function pipeline () {
} }
// TESTING: Move model forward // TESTING: Move model forward
t = t + 0.1 // t = t + 0.1
entity.setPosition([t, 0.0, 0.0]) // entity.setPosition([t, 0.0, 0.0])
}) })
// Render function for the triangle // Render function for the triangle
@ -63,6 +68,7 @@ async function pipeline () {
shader.use(gl) shader.use(gl)
cam.draw(gl, shader) cam.draw(gl, shader)
entity.draw(gl, shader) entity.draw(gl, shader)
planet.draw(gl, shader)
// Use terrain shader // Use terrain shader
terrainShader.use(gl) terrainShader.use(gl)