diff --git a/shaders/unshaded_registered_fragment.fs b/shaders/debug_fragment.fs similarity index 100% rename from shaders/unshaded_registered_fragment.fs rename to shaders/debug_fragment.fs diff --git a/shaders/unshaded_registered_vertex.vs b/shaders/debug_vertex.vs similarity index 100% rename from shaders/unshaded_registered_vertex.vs rename to shaders/debug_vertex.vs diff --git a/shaders/shaded_vertex.vs b/shaders/shaded_vertex.vs index 35ca51e..7790701 100644 --- a/shaders/shaded_vertex.vs +++ b/shaders/shaded_vertex.vs @@ -1,5 +1,3 @@ -uniform vec3 u_fillColour; -uniform float u_opacity; uniform vec3 u_lightWorldPos; uniform mat4 u_worldViewProjection; uniform mat4 u_worldInverseTranspose; @@ -10,14 +8,15 @@ attribute vec3 normal; varying vec4 v_colour; void main() { - vec4 a_position = u_worldViewProjection * vec4(position.xyz * 0.1, 1.0); + vec4 a_position = u_worldViewProjection * vec4(position.xyz, 1.0); vec3 v_normal = (u_worldInverseTranspose * vec4(normal, 0)).xyz; vec3 v_lightDir = normalize(u_lightWorldPos); - float lighting = dot(v_normal, v_lightDir); + float lighting = abs(dot(v_normal, v_lightDir)); - v_colour = vec4(u_fillColour * lighting, u_opacity); + //v_colour = vec4(normal *lighting), 1.0); + v_colour = vec4(vec3(lighting), 1.0); gl_Position = a_position; } diff --git a/shaders/test_fragment.fs b/shaders/test_fragment.fs deleted file mode 100644 index 0133756..0000000 --- a/shaders/test_fragment.fs +++ /dev/null @@ -1,9 +0,0 @@ -precision mediump float; - -//uniform float time; - -void main() { - //float alpha = (-cos(time * 0.05) + 1.0) / 4.0; - float alpha = 1.0; - gl_FragColor = vec4(1.0, 1.0, 1.0, 0.5); -} diff --git a/shaders/test_vertex.vs b/shaders/test_vertex.vs deleted file mode 100644 index 335f174..0000000 --- a/shaders/test_vertex.vs +++ /dev/null @@ -1,11 +0,0 @@ -uniform mat4 u_worldViewProjection; - -attribute vec3 position; -attribute vec3 normal; - -void main() { - // Extrude the vertices outwards slightly to avoid z-fighting - vec3 translated_position = position + normal * 0.0001; - - gl_Position = u_worldViewProjection * vec4(translated_position, 1.0); -} diff --git a/shaders/unshaded_fragment.fs b/shaders/unshaded_fragment.fs deleted file mode 100644 index b793221..0000000 --- a/shaders/unshaded_fragment.fs +++ /dev/null @@ -1,7 +0,0 @@ -precision mediump float; - -uniform vec3 u_fillColour; - -void main() { - gl_FragColor = vec4(u_fillColour, 1.0); -} diff --git a/shaders/unshaded_vertex.vs b/shaders/unshaded_vertex.vs deleted file mode 100644 index b7ee14e..0000000 --- a/shaders/unshaded_vertex.vs +++ /dev/null @@ -1,7 +0,0 @@ -uniform mat4 u_worldViewProjection; - -attribute vec3 position; - -void main() { - gl_Position = u_worldViewProjection * vec4(position.xyz, 1.0); -} diff --git a/src/client.js b/src/client.js index 9e6f187..7b9cef7 100644 --- a/src/client.js +++ b/src/client.js @@ -8,16 +8,10 @@ const renderer = new Renderer(voxelSize); const voxelManager = new VoxelManager(voxelSize); const triangle = new Triangle(new Vector3(0, 0, 0), new Vector3(4, 3, 1), new Vector3(2, -3, -2)); const triangle2 = new Triangle(new Vector3(5, 2, -1), new Vector3(-2, 3, -1), new Vector3(0, 3, 2)); -console.log(triangle2); -renderer.setStroke(new Vector3(1.0, 0.0, 0.0)); -renderer.registerTriangle(triangle); -renderer.registerTriangle(triangle2); - -voxelManager.voxeliseTriangle(triangle); voxelManager.voxeliseTriangle(triangle2); +voxelManager.voxeliseTriangle(triangle); -renderer.setStroke(new Vector3(1.0, 1.0, 1.0)); renderer.registerVoxels(voxelManager.voxels); renderer.compileRegister(); @@ -25,7 +19,6 @@ renderer.compileRegister(); function render(time) { renderer.begin(); - renderer.end(); requestAnimationFrame(render); diff --git a/src/renderer.js b/src/renderer.js index c5687e2..c25fae6 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -18,17 +18,24 @@ class Renderer { this._registerEvents(); - this._register = { + this._debugRegister = { position: {numComponents: 3, data: []}, indices: {numComponents: 3, data: []}, colour: {numComponents: 3, data: []} }; + this._register = { + position: {numComponents: 3, data: []}, + normal: {numComponents: 3, data: []}, + indices: {numComponents: 3, data: []}, + }; + + this._debugMaxIndex = 0; this._maxIndex = 0; - //this._voxelSize = voxelSize; + this._voxelSize = voxelSize; this._voxelSizeVector = new Vector3(voxelSize, voxelSize, voxelSize); - this._registerOpen = true; + this._registersOpen = true; } _registerEvents() { @@ -66,70 +73,124 @@ class Renderer { } compileRegister() { - console.log(this._register); - + this._debugRegisterBuffer = twgl.createBufferInfoFromArrays(this._gl, this._debugRegister); this._registerBuffer = twgl.createBufferInfoFromArrays(this._gl, this._register); - this._registerOpen = false; - } - - end() { - if (this._registerOpen) { - console.error("Trying to draw register objects before register is closed. Call compileRegister() first."); - return; - } - - // Draw objects in register - const uniforms = { - u_worldViewProjection: this._camera.getWorldViewProjection() - }; - - const shader = shaderManager.unshadedRegisteredProgram; - this._gl.useProgram(shader.program); - twgl.setBuffersAndAttributes(this._gl, shader, this._registerBuffer); - twgl.setUniforms(shader, uniforms); - this._gl.drawElements(this._gl.LINES, this._registerBuffer.numElements, this._gl.UNSIGNED_SHORT, 0); + this._registersOpen = false; } setStroke(colour) { this._strokeColour = colour; } - _getBoxData(centre, size) { + end() { + if (this._registersOpen) { + console.error("Trying to draw register objects before register is closed. Call compileRegister() first."); + return; + } + + this._drawDebugRegister(); + this._drawRegister(); + } + + _drawDebugRegister() { + const uniforms = { + u_worldViewProjection: this._camera.getWorldViewProjection() + }; + + this._drawBuffer(this._gl.LINES, this._debugRegisterBuffer, shaderManager.debugProgram, uniforms); + } + + _drawRegister() { + const uniforms = { + //u_lightWorldPos: new Vector3(1, 2, 0.5).toArray(), + u_lightWorldPos: this._camera.getCameraPosition(0.5, 0.0), + u_worldViewProjection: this._camera.getWorldViewProjection(), + u_worldInverseTranspose: this._camera.getWorldInverseTranspose() + }; + + this._drawBuffer(this._gl.TRIANGLES, this._registerBuffer, shaderManager.shadedProgram, uniforms); + } + + _drawBuffer(drawMode, buffer, shader, uniforms) { + this._gl.useProgram(shader.program); + twgl.setBuffersAndAttributes(this._gl, shader, buffer); + twgl.setUniforms(shader, uniforms); + this._gl.drawElements(drawMode, buffer.numElements, this._gl.UNSIGNED_SHORT, 0); + } + + // TODO + _getBoxData(centre, size, debug) { const a = Vector3.sub(centre, Vector3.mulScalar(size, 0.5)); const b = Vector3.add(centre, Vector3.mulScalar(size, 0.5)); - return { - position: [ - a.x, a.y, a.z, - b.x, a.y, a.z, - b.x, b.y, a.z, - a.x, b.y, a.z, - a.x, a.y, b.z, - b.x, a.y, b.z, - b.x, b.y, b.z, - a.x, b.y, b.z - ], - indices: [ - 0, 1, 1, 2, 2, 3, 3, 0, - 4, 5, 5, 6, 6, 7, 7, 4, - 0, 4, 1, 5, 2, 6, 3, 7 - ] - }; + if (debug) { + return { + position: [ + a.x, a.y, a.z, + b.x, a.y, a.z, + b.x, b.y, a.z, + a.x, b.y, a.z, + a.x, a.y, b.z, + b.x, a.y, b.z, + b.x, b.y, b.z, + a.x, b.y, b.z + ], + indices: [ + 0, 1, 1, 2, 2, 3, 3, 0, + 4, 5, 5, 6, 6, 7, 7, 4, + 0, 4, 1, 5, 2, 6, 3, 7 + ] + }; + } else { + let cube = twgl.primitives.createCubeVertices(this._voxelSize); + + for (let i = 0; i < 72; i += 3) { + cube.position[i + 0] += centre.x; + cube.position[i + 1] += centre.y; + cube.position[i + 2] += centre.z; + } + + return cube; + } } - _getTriangleData(a, b, c) { - return { - position: [ - a.x, a.y, a.z, - b.x, b.y, b.z, - c.x, c.y, c.z, - ], - indices: [ - 0, 1, - 1, 2, - 2, 0 - ] - }; + _getTriangleData(triangle, debug) { + + const a = triangle.v0; + const b = triangle.v1; + const c = triangle.v2; + const n = triangle.normal; + + if (debug) { + return { + position: [ + a.x, a.y, a.z, + b.x, b.y, b.z, + c.x, c.y, c.z, + ], + indices: [ + 0, 1, + 1, 2, + 2, 0 + ] + }; + } else { + return { + position: [ + a.x, a.y, a.z, + b.x, b.y, b.z, + c.x, c.y, c.z, + ], + normal: [ + n.x, n.y, n.z, + n.x, n.y, n.z, + n.x, n.y, n.z + ], + indices: [ + 0, 1, 2 + ] + }; + } } /* @@ -149,12 +210,8 @@ class Renderer { // Use when drawing the same thing each frame registerBox(centre, size, debug) { - if (debug) { - const data = this._getBoxData(centre, size); - this._addDataToRegister(data); - } else { - // TODO - } + const data = this._getBoxData(centre, size, debug); + this._addDataToRegister(data, debug); } // Use when drawing the same triangle each frame @@ -163,18 +220,15 @@ class Renderer { const data = this._getTriangleData(a, b, c); this._addDataToRegister(data); }*/ + registerTriangle(triangle, debug) { - if (debug) { - const data = this._getTriangleData(triangle.v0, triangle.v1, triangle.v2); - this._addDataToRegister(data); - } else { - // TODO - } + const data = this._getTriangleData(triangle, debug); + this._addDataToRegister(data, debug); } registerVoxel(centre) { - const data = this._getBoxData(centre, this._voxelSizeVector); - this._addDataToRegister(data); + const data = this._getBoxData(centre, this._voxelSizeVector, false); + this._addDataToRegister(data, false); } registerVoxels(voxelCentres) { @@ -183,23 +237,43 @@ class Renderer { } } - _addDataToRegister(data) { - if (!this._registerOpen) { + _cycleBuffers() { + + } + + _addDataToRegister(data, debug) { + if (!this._registersOpen) { console.error("Trying to register object when register is closed. Register before calling compileRegister()"); return; } - this._register.position.data.push(...data.position); - this._register.indices.data.push(...data.indices.map(x => x + this._maxIndex)); + if (debug) { + this._debugRegister.position.data.push(...data.position); + this._debugRegister.indices.data.push(...data.indices.map(x => x + this._debugMaxIndex)); - const numVertices = data.position.length / 3; - const vertexColours = [].concat(...new Array(numVertices).fill(this._strokeColour.toArray())); - this._register.colour.data.push(...vertexColours); + const numVertices = data.position.length / 3; + const vertexColours = [].concat(...new Array(numVertices).fill(this._strokeColour.toArray())); + this._debugRegister.colour.data.push(...vertexColours); - this._maxIndex += 1 + Math.max(...data.indices); + this._debugMaxIndex += 1 + Math.max(...data.indices); + } else { + const newMaxIndex = this._maxIndex + 1 + Math.max(...data.indices); + if (newMaxIndex >= 65535) { + console.warn("Overloaded buffer"); + return; + } + + this._register.position.data.push(...data.position); + this._register.normal.data.push(...data.normal); + this._register.indices.data.push(...data.indices.map(x => x + this._maxIndex)); + + this._maxIndex = newMaxIndex; + } + + } - + /* _drawData(data) { const buffer = twgl.createBufferInfoFromArrays(this._gl, data); @@ -214,6 +288,7 @@ class Renderer { twgl.setUniforms(shader, uniforms); this._gl.drawElements(this._gl.LINES, buffer.numElements, this._gl.UNSIGNED_SHORT, 0); } + */ } diff --git a/src/shaders.js b/src/shaders.js index 20a08e9..af2395e 100644 --- a/src/shaders.js +++ b/src/shaders.js @@ -1,26 +1,15 @@ const twgl = require('twgl.js'); const fs = require('fs'); - const gl = document.querySelector("#c").getContext("webgl"); const shaded_vertex_shader = fs.readFileSync('./shaders/shaded_vertex.vs', 'utf8'); const shaded_fragment_shader = fs.readFileSync('./shaders/shaded_fragment.fs', 'utf8'); -const unshaded_vertex_shader = fs.readFileSync('./shaders/unshaded_vertex.vs', 'utf8'); -const unshaded_fragment_shader = fs.readFileSync('./shaders/unshaded_fragment.fs', 'utf8'); - -const unshaded_registered_vertex_shader = fs.readFileSync('./shaders/unshaded_registered_vertex.vs', 'utf8'); -const unshaded_registered_fragment_shader = fs.readFileSync('./shaders/unshaded_registered_fragment.fs', 'utf8'); - -const test_vertex_shader = fs.readFileSync('./shaders/test_vertex.vs', 'utf8'); -const test_fragment_shader = fs.readFileSync('./shaders/test_fragment.fs', 'utf8'); +const debug_vertex_shader = fs.readFileSync('./shaders/debug_vertex.vs', 'utf8'); +const debug_fragment_shader = fs.readFileSync('./shaders/debug_fragment.fs', 'utf8'); const shadedProgram = twgl.createProgramInfo(gl, [shaded_vertex_shader, shaded_fragment_shader]); -const unshadedProgram = twgl.createProgramInfo(gl, [unshaded_vertex_shader, unshaded_fragment_shader]); -const unshadedRegisteredProgram = twgl.createProgramInfo(gl, [unshaded_registered_vertex_shader, unshaded_registered_fragment_shader]); -const testProgram = twgl.createProgramInfo(gl, [test_vertex_shader, test_fragment_shader]); +const debugProgram = twgl.createProgramInfo(gl, [debug_vertex_shader, debug_fragment_shader]); module.exports.shadedProgram = shadedProgram; -module.exports.unshadedProgram = unshadedProgram; -module.exports.unshadedRegisteredProgram = unshadedRegisteredProgram; -module.exports.testProgram = testProgram; +module.exports.debugProgram = debugProgram; diff --git a/src/triangle.js b/src/triangle.js index 288fbeb..3632657 100644 --- a/src/triangle.js +++ b/src/triangle.js @@ -9,6 +9,11 @@ class Triangle { this.v1 = v1; this.v2 = v2; + const f0 = Vector3.sub(v1, v0); + const f1 = Vector3.sub(v0, v2); + this.normal = Vector3.cross(f0, f1); + this.normal.normalise(); + this._calculateBoundingBox(); } diff --git a/src/vector.js b/src/vector.js index b65dbbb..f0c78b6 100644 --- a/src/vector.js +++ b/src/vector.js @@ -95,6 +95,17 @@ class Vector3 { return this.x == vec.x && this.y == vec.y && this.z == vec.z; } + _magnitude() { + return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2) + Math.pow(this.z, 2)); + } + + normalise() { + const mag = this._magnitude(); + this.x /= mag; + this.y /= mag; + this.z /= mag; + } + } module.exports.Vector3 = Vector3; \ No newline at end of file