diff --git a/.gitignore b/.gitignore index 06a81ecd..41c155d7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ Debug node_modules prebuilds/* angle/build/* +example/*.ppm \ No newline at end of file diff --git a/binding.gyp b/binding.gyp index fc27ccc5..65384ed9 100644 --- a/binding.gyp +++ b/binding.gyp @@ -12,11 +12,6 @@ 'defines': [ 'VERSION=1.0.0' ], - 'dependencies': - [ - 'angle/src/angle.gyp:libEGL', - 'angle/src/angle.gyp:libGLESv2' - ], 'sources': [ 'src/bindings.cc', 'src/webgl.cc', @@ -32,31 +27,76 @@ ], 'conditions': [ ['OS=="mac"', { + 'dependencies': + [ + 'angle/src/angle.gyp:libEGL', + 'angle/src/angle.gyp:libGLESv2' + ], 'libraries': [ '-framework QuartzCore', '-framework Quartz' ], }], ['OS=="linux"', { + 'dependencies': + [ + 'angle/src/angle.gyp:libEGL', + 'angle/src/angle.gyp:libGLESv2' + ] }], - ['OS=="win"', - { - 'include_dirs': [ - ], + ['OS=="win"', { 'library_dirs': [ - ], + '<(module_root_dir)/deps/windows/lib/<(target_arch)', + ], 'libraries': [ - ], + 'libEGL.lib', + 'libGLESv2.lib' + ], 'defines' : [ 'WIN32_LEAN_AND_MEAN', 'VC_EXTRALEAN' ], - 'cflags' : [ - '/O2','/Oy','/GL','/GF','/Gm-','/EHsc','/MT','/GS','/Gy','/GR-','/Gd','/wd"4530"','/wd"4251"' - ], - 'ldflags' : [ - '/OPT:REF','/OPT:ICF','/LTCG' - ] + 'configurations': { + 'Release': { + 'msvs_settings': { + 'VCCLCompilerTool': { + 'RuntimeLibrary': 0, # static release + 'Optimization': 0, # /Od, disabled + 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size + 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible + 'WholeProgramOptimization': 'false', # No + 'OmitFramePointers': 'true', + 'EnableFunctionLevelLinking': 'true', + 'EnableIntrinsicFunctions': 'true', + 'RuntimeTypeInfo': 'false', + 'ExceptionHandling': '0', + 'AdditionalOptions': [ + '/MP', # compile across multiple CPUs + ] + }, + 'VCLinkerTool': { + 'LinkTimeCodeGeneration': 0, # Link Time Code generation default + 'OptimizeReferences': 1, # /OPT:NOREF + 'EnableCOMDATFolding': 1, # /OPT:NOICF + 'LinkIncremental': 2, # /INCREMENTAL + } + }, + 'msvs_configuration_attributes': + { + 'OutputDirectory': '$(SolutionDir)$(ConfigurationName)', + 'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)' + } + } + }, + "copies": [ + { + 'destination': '$(SolutionDir)$(ConfigurationName)', + 'files': [ + '<(module_root_dir)/deps/windows/dll/<(target_arch)/libEGL.dll', + '<(module_root_dir)/deps/windows/dll/<(target_arch)/libGLESv2.dll' + ] + } + ] } ] ] diff --git a/deps/windows/dll/x64/libEGL.dll b/deps/windows/dll/x64/libEGL.dll new file mode 100755 index 00000000..e2785665 Binary files /dev/null and b/deps/windows/dll/x64/libEGL.dll differ diff --git a/deps/windows/dll/x64/libGLESv2.dll b/deps/windows/dll/x64/libGLESv2.dll new file mode 100755 index 00000000..d51782e4 Binary files /dev/null and b/deps/windows/dll/x64/libGLESv2.dll differ diff --git a/deps/windows/lib/x64/libEGL.lib b/deps/windows/lib/x64/libEGL.lib new file mode 100755 index 00000000..1c250629 Binary files /dev/null and b/deps/windows/lib/x64/libEGL.lib differ diff --git a/deps/windows/lib/x64/libGLESv2.lib b/deps/windows/lib/x64/libGLESv2.lib new file mode 100755 index 00000000..cdb1d9fd Binary files /dev/null and b/deps/windows/lib/x64/libGLESv2.lib differ diff --git a/example/fbo.js b/example/fbo.js index 06570e55..623e11cb 100644 --- a/example/fbo.js +++ b/example/fbo.js @@ -1,19 +1,20 @@ -// Create context -var width = 256 -var height = 256 -var gl = require('../index.js')(width, height) +var createContext = require('../index'); +var utils = require('./utils.js'); -// Clear screen to red -gl.clearColor(1.0, 1.0, 1.0, 1.0) -gl.colorMask(true, true, true, true) -gl.clear(gl.COLOR_BUFFER_BIT) +function main() { + // Create context + var width = 64 + var height = 64 + var gl = createContext(width, height) -// Write output -var pixels = new Uint8Array(width * height * 4) -gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels) -process.stdout.write(['P3\n# gl.ppm\n', width, ' ', height, '\n255\n'].join('')) -for (var i = 0; i < pixels.length; i += 3) { - process.stdout.write(pixels[i] + ' ' + pixels[i + 1] + ' ' + pixels[i + 2] + ' ') + // Clear screen to red + gl.clearColor(1.0, 0.0, 0.0, 1.0) + gl.colorMask(true, true, true, true) + gl.clear(gl.COLOR_BUFFER_BIT) + + utils.dumpBuffer(gl, width, height) + + gl.destroy() } -gl.destroy() +main(); \ No newline at end of file diff --git a/example/test1.js b/example/test1.js new file mode 100755 index 00000000..228f8f7d --- /dev/null +++ b/example/test1.js @@ -0,0 +1,59 @@ +var createContext = require('../index') +var utils = require('./utils'); + +function main() { + // Create context + var width = 64 + var height = 64 + var gl = createContext(width, height) + + var vertex_src = [ + 'attribute vec2 a_position;', + 'void main() {', + 'gl_Position = vec4(a_position, 0, 1);', + '}' + ].join('\n') + + var fragment_src = [ + 'void main() {', + 'gl_FragColor = vec4(0, 1, 0, 1); // green', + '}' + ].join('\n') + + // setup a GLSL program + var program = utils.createProgramFromSources(gl, [vertex_src, fragment_src]); + + if(!program) { + return; + } + gl.useProgram(program); + + // look up where the vertex data needs to go. + var positionLocation = gl.getAttribLocation(program, "a_position"); + + // Create a buffer and put a single clipspace rectangle in + // it (2 triangles) + var buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([ + -1.0, -1.0, + 1.0, -1.0, + -1.0, 1.0, + -1.0, 1.0, + 1.0, -1.0, + 1.0, 1.0]), + gl.STATIC_DRAW); + gl.enableVertexAttribArray(positionLocation); + gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); + + // draw + gl.drawArrays(gl.TRIANGLES, 0, 6); + + utils.dumpBuffer(gl, width, height) + + gl.destroy() +} + +main(); \ No newline at end of file diff --git a/example/utils.js b/example/utils.js new file mode 100755 index 00000000..f06fbfef --- /dev/null +++ b/example/utils.js @@ -0,0 +1,87 @@ +function dumpBuffer(gl, width, height) { + // Write output + var pixels = new Uint8Array(width * height * 4) + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels) + process.stdout.write(['P3\n# gl.ppm\n', width, ' ', height, '\n255\n'].join('')) + for (var i = 0; i < pixels.length; i += 4) { + process.stdout.write(pixels[i] + ' ' + pixels[i + 1] + ' ' + pixels[i + 2] + ' ') + } +} + +function drawTriangle(gl) { + var buffer = gl.createBuffer() + gl.bindBuffer(gl.ARRAY_BUFFER, buffer) + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-2, -2, -2, 4, 4, -2]), gl.STREAM_DRAW) + gl.enableVertexAttribArray(0) + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0) + gl.drawArrays(gl.TRIANGLES, 0, 3) + gl.bindBuffer(gl.ARRAY_BUFFER, null) + gl.disableVertexAttribArray(0) + gl.deleteBuffer(buffer) +} + +function loadShader(gl, shaderSource, shaderType) { + var shader = gl.createShader(shaderType); + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + + // Check the compile status + var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var lastError = gl.getShaderInfoLog(shader); + console.log("*** Error compiling shader '" + shader + "':" + lastError); + gl.deleteShader(shader); + return null; + } + + return shader; +} + +function createProgram(gl, shaders, opt_attribs, opt_locations) { + var program = gl.createProgram(); + shaders.forEach(function(shader) { + gl.attachShader(program, shader); + }); + if (opt_attribs) { + obj_attrib.forEach(function(attrib, ndx) { + gl.bindAttribLocation( + program, + opt_locations ? opt_locations[ndx] : ndx, + attrib); + }); + } + gl.linkProgram(program); + + // Check the link status + var linked = gl.getProgramParameter(program, gl.LINK_STATUS); + if (!linked) { + // something went wrong with the link + var lastError = gl.getProgramInfoLog(program); + console.log("Error in program linking:" + lastError); + + gl.deleteProgram(program); + return null; + } + return program; +} + +function createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations) { + var defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER", + ]; + + var shaders = []; + for (var ii = 0; ii < shaderSources.length; ++ii) { + shaders.push(loadShader(gl, shaderSources[ii], gl[defaultShaderType[ii]])); + } + return createProgram(gl, shaders, opt_attribs, opt_locations); +} + + +module.exports.dumpBuffer = dumpBuffer; +module.exports.drawTriangle = drawTriangle; +module.exports.loadShader = loadShader; +module.exports.createProgram = createProgram; +module.exports.createProgramFromSources = createProgramFromSources; \ No newline at end of file