diff options
Diffstat (limited to 'src/library_gl.js')
-rw-r--r-- | src/library_gl.js | 141 |
1 files changed, 136 insertions, 5 deletions
diff --git a/src/library_gl.js b/src/library_gl.js index 7c5cca0b..50a3b7fa 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -784,6 +784,11 @@ var LibraryGL = { return Module.ctx.isFramebuffer(fb); }, + glEnable: function(cap) { + if (cap == 0x0DE1) return; // no GL_TEXTURE_2D in GLES or WebGL + Module.ctx.enable(cap); + }, + // GL emulation: provides misc. functionality not present in OpenGL ES 2.0 or WebGL $GLEmulation__deps: ['glCreateShader', 'glShaderSource', 'glCompileShader', 'glCreateProgram', 'glDeleteShader', 'glDeleteProgram', 'glAttachShader', 'glActiveTexture', 'glGetShaderiv', 'glGetProgramiv', 'glLinkProgram'], @@ -838,15 +843,141 @@ var LibraryGL = { } }, - glBegin__deps: ['$GL', function() { return 'GL.matrix.lib = ' + read('gl-matrix.js') }], - glBegin: function() { - Module.print('TODO'); - } + // Immediate mode + + $GLImmediate: { + maxElements: 1024, + vertexData: null, + indexData: null, + vertexCounter: 0, + indexCounter: 0, + mode: 0, + + initted: false, + init: function() { + this.vertexShader = Module.ctx.createShader(Module.ctx.VERTEX_SHADER); + Module.ctx.shaderSource(this.vertexShader, 'attribute vec4 a_position; \n\ + attribute vec2 a_texCoord; \n\ + varying vec2 v_texCoord; \n\ + void main() \n\ + { \n\ + gl_Position = a_position; \n\ + v_texCoord = a_texCoord; \n\ + } \n'); + Module.ctx.compileShader(this.vertexShader); + + this.fragmentShader = Module.ctx.createShader(Module.ctx.FRAGMENT_SHADER); + Module.ctx.shaderSource(this.fragmentShader, 'precision mediump float; \n\ + varying vec2 v_texCoord; \n\ + uniform sampler2D s_texture; \n\ + void main() \n\ + { \n\ + gl_FragColor = texture2D( s_texture, v_texCoord );\n\ + } \n'); + Module.ctx.compileShader(this.fragmentShader); + + this.program = Module.ctx.createProgram(); + Module.ctx.attachShader(this.program, this.vertexShader); + Module.ctx.attachShader(this.program, this.fragmentShader); + Module.ctx.linkProgram(this.program); + + this.positionLocation = Module.ctx.getAttribLocation(this.program, 'a_position'); + this.texCoordLocation = Module.ctx.getAttribLocation(this.program, 'a_texCoord'); + this.textureLocation = Module.ctx.getUniformLocation(this.program, 's_texture'); + + // Buffer for data + this.vertexData = new Float32Array(5 * this.maxElements); + this.indexData = new Uint16Array(this.maxElements); + + this.vertexObject = Module.ctx.createBuffer(); + this.indexObject = Module.ctx.createBuffer(); + }, + flush: function() { + // Upload the data + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject); + Module.ctx.bufferData(Module.ctx.ARRAY_BUFFER, this.vertexData.subarray(0, 5*this.vertexCounter), Module.ctx.STATIC_DRAW); + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject); + Module.ctx.bufferData(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexData.subarray(0, this.indexCounter), Module.ctx.STATIC_DRAW); + + // Render + Module.ctx.viewport(0, 0, Module.canvas.width, Module.canvas.height); + Module.ctx.clear(Module.ctx.COLOR_BUFFER_BIT); + + Module.ctx.useProgram(this.program); + + Module.ctx.bindBuffer(Module.ctx.ARRAY_BUFFER, this.vertexObject); + Module.ctx.vertexAttribPointer(this.positionLocation, 3, Module.ctx.FLOAT, + false, 5 * 4, 0); + Module.ctx.vertexAttribPointer(this.texCoordLocation, 2, Module.ctx.FLOAT, + false, 5 * 4, + 3 * 4); + + Module.ctx.enableVertexAttribArray(this.positionLoc); + Module.ctx.enableVertexAttribArray(this.texCoordLoc); + + Module.ctx.activeTexture(Module.ctx.TEXTURE0); + Module.ctx.bindTexture(Module.ctx.TEXTURE_2D, this.textureId); + + Module.ctx.uniform1i(this.textureLocation, 0); + + Module.ctx.bindBuffer(Module.ctx.ELEMENT_ARRAY_BUFFER, this.indexObject); + Module.ctx.drawElements(Module.ctx.TRIANGLES, this.indexCounter, Module.ctx.UNSIGNED_SHORT, 0); + + this.vertexCounter = this.indexCounter = 0; + } + }, + + glBegin__deps: ['$GL', '$GLImmediate', function() { return 'GL.matrix.lib = ' + read('gl-matrix.js') + ';\nGL.immediate = GLImmediate;\n' }], + glBegin: function(mode) { + if (!GL.immediate.initted) GL.immediate.init(); + GL.immediate.mode = mode; + }, + + glEnd: function() { + GL.immediate.flush(); + }, + + glVertex3f: function(x, y, z) { + GL.immediate.vertexData[5*GL.immediate.vertexCounter ] = x; + GL.immediate.vertexData[5*GL.immediate.vertexCounter+1] = y; + GL.immediate.vertexData[5*GL.immediate.vertexCounter+2] = z; + GL.immediate.vertexCounter++; +#if ASSERTIONS + assert(GL.immediate.vertexCounter < GL.immediate.maxElements, 'too many immediate mode vertexes'); +#endif + if (GL.immediate.mode == 7) { // GL_QUADS + if (GL.immediate.vertexCounter % 4 == 0) { + var start = GL.immediate.vertexCounter % 4; + GL.immediate.indexData[GL.immediate.indexCounter ] = start; + GL.immediate.indexData[GL.immediate.indexCounter+1] = start+1; + GL.immediate.indexData[GL.immediate.indexCounter+2] = start+2; + GL.immediate.indexData[GL.immediate.indexCounter+3] = start; + GL.immediate.indexData[GL.immediate.indexCounter+4] = start+2; + GL.immediate.indexData[GL.immediate.indexCounter+5] = start+3; + GL.immediate.indexCounter += 6; + } + } else { + throw 'only GL_QUADS supported so far'; + } +#if ASSERTIONS + assert(GL.immediate.indexCounter < GL.immediate.maxElements, 'too many immediate mode indexes'); +#endif + }, + + glTexCoord2i: function(u, v) { + GL.immediate.vertexData[5*GL.immediate.vertexCounter+3] = u; + GL.immediate.vertexData[5*GL.immediate.vertexCounter+4] = v; + }, + + // TODO + glMatrixMode: function(){}, + glLoadIdentity: function(){}, + glOrtho: function(){}, }; // Simple pass-through functions. Starred ones have return values. [[0, 'shadeModel fogi fogfv getError finish flush'], - [1, 'clearDepth depthFunc enable disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus* generateMipmap activeTexture blendEquation'], + [1, 'clearDepth depthFunc disable frontFace cullFace clear enableVertexAttribArray disableVertexAttribArray lineWidth clearStencil depthMask stencilMask stencilMaskSeparate checkFramebufferStatus* generateMipmap activeTexture blendEquation'], [2, 'pixelStorei blendFunc blendEquationSeparate'], [3, 'texParameteri texParameterf drawArrays vertexAttrib2f'], [4, 'viewport clearColor scissor vertexAttrib3f colorMask drawElements renderbufferStorage blendFuncSeparate'], |