From a5e69edc5a6f1a95618c04e214d39b397577d796 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 11 Sep 2017 23:24:13 +0200 Subject: Code structuring Also, use a fixed-size canvas for now. --- src/default.fs | 3 -- src/default.vs | 8 --- src/index.ts | 138 ++------------------------------------------------- src/view/Renderer.ts | 124 +++++++++++++++++++++++++++++++++++++++++++++ src/view/Scene.ts | 41 +++++++++++++++ src/view/default.fs | 3 ++ src/view/default.vs | 8 +++ 7 files changed, 181 insertions(+), 144 deletions(-) delete mode 100644 src/default.fs delete mode 100644 src/default.vs create mode 100644 src/view/Renderer.ts create mode 100644 src/view/Scene.ts create mode 100644 src/view/default.fs create mode 100644 src/view/default.vs (limited to 'src') diff --git a/src/default.fs b/src/default.fs deleted file mode 100644 index 7a085b6..0000000 --- a/src/default.fs +++ /dev/null @@ -1,3 +0,0 @@ -void main(void) { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); -} diff --git a/src/default.vs b/src/default.vs deleted file mode 100644 index 457a528..0000000 --- a/src/default.vs +++ /dev/null @@ -1,8 +0,0 @@ -attribute vec3 aVertexPosition; - -uniform mat4 uVMatrix; -uniform mat4 uPMatrix; - -void main(void) { - gl_Position = uPMatrix * uVMatrix * vec4(aVertexPosition, 1.0); -} diff --git a/src/index.ts b/src/index.ts index 8a5a067..718a321 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,141 +1,13 @@ -import {mat4} from 'gl-matrix'; +import Renderer from './view/Renderer'; +import Scene from './view/Scene'; (() => { - const body = document.getElementsByTagName('body')[0]; - const canvas = document.getElementById('rpgedit') as HTMLCanvasElement; if (!canvas) return; - const gl = canvas.getContext('webgl') as WebGLRenderingContext; - if (!gl) - return; - - gl.clearColor(0.0, 0.0, 0.0, 1.0); - gl.enable(gl.DEPTH_TEST); - - - function compileShader(type: number, src: string): WebGLShader|null { - let shader = gl.createShader(type); - if (!shader) { - console.error('Unable to create shader'); - return null; - } - - gl.shaderSource(shader, src); - gl.compileShader(shader); - - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - console.error('Unable to compile shader'); - return null; - } - - return shader; - } - - - let shaderVertexPositionAttribute: number; - let shaderPMatrixUniform: WebGLUniformLocation|null; - let shaderVMatrixUniform: WebGLUniformLocation|null; - - function initShaders(): void { - let shaderProgram = gl.createProgram(); - - let vertexShader = compileShader(gl.VERTEX_SHADER, require('./default.vs')); - - let fragmentShaderSrc = require('./default.fs'); - let fragmentShader = compileShader(gl.FRAGMENT_SHADER, require('./default.fs')); - - if (!vertexShader || !fragmentShader) - return; - - gl.attachShader(shaderProgram, vertexShader); - gl.attachShader(shaderProgram, fragmentShader); - - gl.linkProgram(shaderProgram); - if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - console.error('Unable to link shader'); - return; - } - - gl.useProgram(shaderProgram); - - shaderVertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); - gl.enableVertexAttribArray(shaderVertexPositionAttribute); - - shaderPMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); - shaderVMatrixUniform = gl.getUniformLocation(shaderProgram, "uVMatrix"); - } - - - const triangleVertexPositionBuffer = gl.createBuffer(); - const squareVertexPositionBuffer = gl.createBuffer(); - - function initScene(): void { - gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); - const triangleVertices = [ - 0.0, 1.0, 0.0, - -1.0, -1.0, 0.0, - 1.0, -1.0, 0.0 - ]; - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW); - - gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); - const squareVertices = [ - 1.0, 1.0, 0.0, - -1.0, 1.0, 0.0, - 1.0, -1.0, 0.0, - -1.0, -1.0, 0.0 - ]; - gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareVertices), gl.STATIC_DRAW); - } - - initShaders(); - initScene(); - - const pMatrix = mat4.create(); - const vMatrix = mat4.create(); - - function drawScene(): void { - if (!shaderPMatrixUniform || !shaderVMatrixUniform) - return; - - let width = canvas.width, height = canvas.height - - gl.viewport(0, 0, width, height); - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - - mat4.perspective(pMatrix, 45, width / height, 0.1, 100.0); - gl.uniformMatrix4fv(shaderPMatrixUniform, false, pMatrix); - - mat4.identity(vMatrix); - mat4.translate(vMatrix, vMatrix, [-1.5, 0.0, -7.0]); - gl.uniformMatrix4fv(shaderVMatrixUniform, false, vMatrix); - - gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); - gl.vertexAttribPointer(shaderVertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); - gl.drawArrays(gl.TRIANGLES, 0, 3); - - mat4.translate(vMatrix, vMatrix, [3.0, 0.0, 0.0]); - gl.uniformMatrix4fv(shaderVMatrixUniform, false, vMatrix); - - gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); - gl.vertexAttribPointer(shaderVertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - function setSize(): void { - var e = document.documentElement; - var w = window.innerWidth || e.clientWidth || body.clientWidth; - var h = window.innerHeight || e.clientHeight || body.clientHeight; - - canvas.width = w; - canvas.height = h; - - drawScene() - } - - window.addEventListener('resize', () => setSize()); - setSize(); + const renderer = new Renderer(canvas); + const scene = new Scene(renderer); + scene.draw(); })(); diff --git a/src/view/Renderer.ts b/src/view/Renderer.ts new file mode 100644 index 0000000..556cfe3 --- /dev/null +++ b/src/view/Renderer.ts @@ -0,0 +1,124 @@ +import {mat4} from 'gl-matrix'; + + +class Renderer { + public gl: WebGLRenderingContext; + + public vertexPosLoc: number; + private viewportLoc: WebGLUniformLocation; + private translateLoc: WebGLUniformLocation; + + private viewport: mat4 = mat4.create(); + private translate: mat4 = mat4.create(); + + private mkContext(): WebGLRenderingContext { + let gl = (this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl')) as WebGLRenderingContext|null; + if (!gl) + throw new Error('unable to initialize WebGL context'); + + return gl; + } + + getAttribLocation(program: WebGLProgram, name: string): number { + let ret = this.gl.getAttribLocation(program, name); + if (ret < 0) + throw new Error('unable to get location of attribute \'' + name + '\''); + + return ret; + } + + getUniformLocation(program: WebGLProgram, name: string): WebGLUniformLocation { + let ret = this.gl.getUniformLocation(program, name); + if (!ret) + throw new Error('unable to get location of uniform \'' + name + '\''); + + return ret; + } + + createBuffer(): WebGLBuffer { + let ret = this.gl.createBuffer(); + if (!ret) + throw new Error('unable to create buffer'); + + return ret; + } + + compileShader(type: number, src: string): WebGLShader { + let shader = this.gl.createShader(type); + if (!shader) { + throw new Error('Unable to create shader'); + } + + this.gl.shaderSource(shader, src); + this.gl.compileShader(shader); + + if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) { + let err = this.gl.getShaderInfoLog(shader); + this.gl.deleteShader(shader); + throw new Error('Unable to compile shader: ' + err); + } + + return shader; + } + + private initShaders(): void { + let shaderProgram = this.gl.createProgram(); + if (!shaderProgram) { + throw new Error('Unable to create shader program'); + } + + let vertexShader = this.compileShader(this.gl.VERTEX_SHADER, require('./default.vs')); + let fragmentShader = this.compileShader(this.gl.FRAGMENT_SHADER, require('./default.fs')); + + + this.gl.attachShader(shaderProgram, vertexShader); + this.gl.attachShader(shaderProgram, fragmentShader); + + this.gl.linkProgram(shaderProgram); + if (!this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS)) { + let err = this.gl.getProgramInfoLog(shaderProgram); + + this.gl.deleteShader(vertexShader); + this.gl.deleteShader(fragmentShader); + this.gl.deleteProgram(shaderProgram); + + throw new Error('Unable to link shader: ' + err); + } + + this.gl.useProgram(shaderProgram); + + this.vertexPosLoc = this.getAttribLocation(shaderProgram, 'vertexPos'); + this.gl.enableVertexAttribArray(this.vertexPosLoc); + + this.viewportLoc = this.getUniformLocation(shaderProgram, 'viewport'); + this.translateLoc = this.getUniformLocation(shaderProgram, 'translate'); + } + + private setSize(): void { + let w = this.canvas.width; + let h = this.canvas.height; + + this.gl.viewport(0, 0, w, h); + this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); + + mat4.identity(this.viewport); + mat4.scale(this.viewport, this.viewport, [64 / w, 64 / h, 1.0]); + this.gl.uniformMatrix4fv(this.viewportLoc, false, this.viewport); + + mat4.identity(this.translate); + this.gl.uniformMatrix4fv(this.translateLoc, false, this.translate); + } + + constructor(private canvas: HTMLCanvasElement) { + this.gl = this.mkContext(); + + this.initShaders(); + + this.gl.clearColor(0.0, 0.0, 0.0, 1.0); + this.gl.enable(this.gl.DEPTH_TEST); + + this.setSize(); + } +} + +export default Renderer; diff --git a/src/view/Scene.ts b/src/view/Scene.ts new file mode 100644 index 0000000..0de7546 --- /dev/null +++ b/src/view/Scene.ts @@ -0,0 +1,41 @@ +import Renderer from './Renderer'; + +class Scene { + private triangleVertexPositionBuffer: WebGLBuffer; + private squareVertexPositionBuffer: WebGLBuffer; + + constructor(private r: Renderer) { + this.triangleVertexPositionBuffer = r.createBuffer(); + r.gl.bindBuffer(r.gl.ARRAY_BUFFER, this.triangleVertexPositionBuffer); + const triangleVertices = [ + -1.5, 1.0, + -2.5, -1.0, + -0.5, -1.0, + ]; + r.gl.bufferData(r.gl.ARRAY_BUFFER, new Float32Array(triangleVertices), r.gl.STATIC_DRAW); + + this.squareVertexPositionBuffer = r.createBuffer(); + r.gl.bindBuffer(r.gl.ARRAY_BUFFER, this.squareVertexPositionBuffer); + const squareVertices = [ + 2.5, 1.0, + 0.5, 1.0, + 2.5, -1.0, + 0.5, -1.0, + ]; + r.gl.bufferData(r.gl.ARRAY_BUFFER, new Float32Array(squareVertices), r.gl.STATIC_DRAW); + } + + draw(): void { + this.r.gl.clear(this.r.gl.COLOR_BUFFER_BIT | this.r.gl.DEPTH_BUFFER_BIT); + + this.r.gl.bindBuffer(this.r.gl.ARRAY_BUFFER, this.triangleVertexPositionBuffer); + this.r.gl.vertexAttribPointer(this.r.vertexPosLoc, 2, this.r.gl.FLOAT, false, 0, 0); + this.r.gl.drawArrays(this.r.gl.TRIANGLES, 0, 3); + + this.r.gl.bindBuffer(this.r.gl.ARRAY_BUFFER, this.squareVertexPositionBuffer); + this.r.gl.vertexAttribPointer(this.r.vertexPosLoc, 2, this.r.gl.FLOAT, false, 0, 0); + this.r.gl.drawArrays(this.r.gl.TRIANGLE_STRIP, 0, 4); + } +} + +export default Scene; diff --git a/src/view/default.fs b/src/view/default.fs new file mode 100644 index 0000000..7a085b6 --- /dev/null +++ b/src/view/default.fs @@ -0,0 +1,3 @@ +void main(void) { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); +} diff --git a/src/view/default.vs b/src/view/default.vs new file mode 100644 index 0000000..7c4eaeb --- /dev/null +++ b/src/view/default.vs @@ -0,0 +1,8 @@ +attribute vec2 vertexPos; + +uniform mat4 viewport; +uniform mat4 translate; + +void main(void) { + gl_Position = viewport * translate * vec4(vertexPos, 0.0, 1.0); +} -- cgit v1.2.3