From 720a2090fbfd5e267d3c6f186dc28b98b22f50b3 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Sat, 2 Aug 2014 13:47:02 -0700 Subject: [PATCH] Update samples --- lime/audio/ALAudioContext.hx | 4 +- lime/audio/AudioBuffer.hx | 6 +- lime/audio/AudioSource.hx | 25 +- lime/audio/openal/AL.hx | 4 +- samples/HelloWorld/project.xml | 2 +- samples/HerokuShaders/HerokuShaders.hxproj | 19 +- samples/HerokuShaders/Source/Main.hx | 121 ++++--- samples/HerokuShaders/project.lime | 15 - samples/HerokuShaders/project.xml | 14 + .../Assets/ambience.ogg | Bin .../Assets/license.txt} | 0 .../Assets/sound.ogg | Bin .../Assets/sound.wav | Bin .../SimpleAudio.hxproj} | 17 +- samples/SimpleAudio/Source/Main.hx | 74 ++++ samples/SimpleAudio/project.xml | 14 + samples/SimpleAudioExample/Assets/.keep | 0 samples/SimpleAudioExample/project.lime.xml | 30 -- samples/SimpleAudioExample/src/Main.hx | 106 ------ samples/SimpleOpenGL/Assets/lime.png | Bin 41090 -> 0 bytes samples/SimpleOpenGL/Assets/lime.svg | 54 --- samples/SimpleOpenGL/Source/Main.hx | 320 ------------------ samples/SimpleOpenGL/project.lime | 17 - 23 files changed, 224 insertions(+), 618 deletions(-) delete mode 100644 samples/HerokuShaders/project.lime create mode 100644 samples/HerokuShaders/project.xml rename samples/{SimpleAudioExample => SimpleAudio}/Assets/ambience.ogg (100%) rename samples/{SimpleAudioExample/Assets/sound_licenses.txt => SimpleAudio/Assets/license.txt} (100%) rename samples/{SimpleAudioExample => SimpleAudio}/Assets/sound.ogg (100%) rename samples/{SimpleAudioExample => SimpleAudio}/Assets/sound.wav (100%) rename samples/{SimpleOpenGL/SimpleOpenGLView.hxproj => SimpleAudio/SimpleAudio.hxproj} (74%) create mode 100644 samples/SimpleAudio/Source/Main.hx create mode 100644 samples/SimpleAudio/project.xml delete mode 100644 samples/SimpleAudioExample/Assets/.keep delete mode 100644 samples/SimpleAudioExample/project.lime.xml delete mode 100644 samples/SimpleAudioExample/src/Main.hx delete mode 100644 samples/SimpleOpenGL/Assets/lime.png delete mode 100644 samples/SimpleOpenGL/Assets/lime.svg delete mode 100644 samples/SimpleOpenGL/Source/Main.hx delete mode 100644 samples/SimpleOpenGL/project.lime diff --git a/lime/audio/ALAudioContext.hx b/lime/audio/ALAudioContext.hx index b79d927c1..3e181e4e4 100644 --- a/lime/audio/ALAudioContext.hx +++ b/lime/audio/ALAudioContext.hx @@ -2,7 +2,7 @@ package lime.audio; import lime.audio.openal.AL; -import lime.utils.Float32Array; +import lime.utils.ByteArray; class ALAudioContext { @@ -79,7 +79,7 @@ class ALAudioContext { } - public function bufferData (buffer:Int, format:Int, data:Float32Array, size:Int, freq:Int):Void { + public function bufferData (buffer:Int, format:Int, data:ByteArray, size:Int, freq:Int):Void { AL.bufferData (buffer, format, data, size, freq); diff --git a/lime/audio/AudioBuffer.hx b/lime/audio/AudioBuffer.hx index 1e2099f6a..5dd8ac7a1 100644 --- a/lime/audio/AudioBuffer.hx +++ b/lime/audio/AudioBuffer.hx @@ -18,7 +18,7 @@ class AudioBuffer { public var bitsPerSample:Int; public var channels:Int; - public var data:Float32Array; + public var data:ByteArray; public var id:UInt; public var sampleRate:Int; @@ -53,7 +53,7 @@ class AudioBuffer { var audioBuffer = new AudioBuffer (); audioBuffer.bitsPerSample = data.bitsPerSample; audioBuffer.channels = data.channels; - audioBuffer.data = new Float32Array (data.data); + audioBuffer.data = data.data; audioBuffer.sampleRate = data.sampleRate; return audioBuffer; @@ -74,7 +74,7 @@ class AudioBuffer { var audioBuffer = new AudioBuffer (); audioBuffer.bitsPerSample = data.bitsPerSample; audioBuffer.channels = data.channels; - audioBuffer.data = new Float32Array (data.data); + audioBuffer.data = data.data; audioBuffer.sampleRate = data.sampleRate; return audioBuffer; diff --git a/lime/audio/AudioSource.hx b/lime/audio/AudioSource.hx index 9fc749d04..330a46e82 100644 --- a/lime/audio/AudioSource.hx +++ b/lime/audio/AudioSource.hx @@ -4,6 +4,10 @@ package lime.audio; import lime.app.Event; import lime.audio.openal.AL; +#if flash +import flash.media.SoundChannel; +#end + class AudioSource { @@ -15,12 +19,18 @@ class AudioSource { public var timeOffset (get, set):Int; private var id:UInt; + private var pauseTime:Int; + + #if flash + private var channel:SoundChannel; + #end public function new (buffer:AudioBuffer = null) { this.buffer = buffer; id = 0; + pauseTime = 0; if (buffer != null) { @@ -69,7 +79,7 @@ class AudioSource { } - al.bufferData (buffer.id, format, buffer.data, buffer.data.length << 2, buffer.sampleRate); + al.bufferData (buffer.id, format, buffer.data, buffer.data.length, buffer.sampleRate); } @@ -87,7 +97,8 @@ class AudioSource { #if js #elseif flash - buffer.src.play (); + if (channel != null) channel.stop (); + var channel = buffer.src.play (pauseTime / 1000); #else AL.sourcePlay (id); #end @@ -99,7 +110,12 @@ class AudioSource { #if js #elseif flash - buffer.src.pause (); + if (channel != null) { + + pauseTime = Std.int (channel.position * 1000); + channel.stop (); + + } #else AL.sourcePause (id); #end @@ -111,7 +127,8 @@ class AudioSource { #if js #elseif flash - buffer.src.stop (); + pauseTime = 0; + if (channel != null) channel.stop (); #else AL.sourceStop (id); #end diff --git a/lime/audio/openal/AL.hx b/lime/audio/openal/AL.hx index 112a24637..d815ff21a 100644 --- a/lime/audio/openal/AL.hx +++ b/lime/audio/openal/AL.hx @@ -2,7 +2,7 @@ package lime.audio.openal; import lime.system.System; -import lime.utils.Float32Array; +import lime.utils.ByteArray; class AL { @@ -72,7 +72,7 @@ class AL { public static inline var EXPONENT_DISTANCE_CLAMPED:Int = 0xD006; - public static function bufferData (buffer:Int, format:Int, data:Float32Array, size:Int, freq:Int):Void { + public static function bufferData (buffer:Int, format:Int, data:ByteArray, size:Int, freq:Int):Void { #if (cpp || neko) lime_al_buffer_data (buffer, format, data.getByteBuffer (), size, freq); diff --git a/samples/HelloWorld/project.xml b/samples/HelloWorld/project.xml index d95e0b946..284979743 100644 --- a/samples/HelloWorld/project.xml +++ b/samples/HelloWorld/project.xml @@ -1,7 +1,7 @@ - + diff --git a/samples/HerokuShaders/HerokuShaders.hxproj b/samples/HerokuShaders/HerokuShaders.hxproj index 2000dc231..3c5128197 100644 --- a/samples/HerokuShaders/HerokuShaders.hxproj +++ b/samples/HerokuShaders/HerokuShaders.hxproj @@ -4,30 +4,33 @@ - + - + + + - - + @@ -39,7 +42,7 @@ - + @@ -53,4 +56,4 @@ - + \ No newline at end of file diff --git a/samples/HerokuShaders/Source/Main.hx b/samples/HerokuShaders/Source/Main.hx index 4f44f9a51..529ead755 100644 --- a/samples/HerokuShaders/Source/Main.hx +++ b/samples/HerokuShaders/Source/Main.hx @@ -2,18 +2,18 @@ package; import haxe.Timer; -import lime.gl.GL; -import lime.gl.GLBuffer; -import lime.gl.GLProgram; -import lime.gl.GLShader; -import lime.gl.GLUniformLocation; -import lime.utils.Matrix3D; +import lime.app.Application; +import lime.graphics.opengl.GL; +import lime.graphics.opengl.GLBuffer; +import lime.graphics.opengl.GLProgram; +import lime.graphics.opengl.GLShader; +import lime.graphics.opengl.GLUniformLocation; +import lime.graphics.RenderContext; import lime.utils.Float32Array; -import lime.utils.Assets; -import lime.Lime; +import lime.Assets; -class Main { +class Main extends Application { private static var fragmentShaders = [ #if mobile "6284.1", "6238", "6147.1", "5891.5", "5805.18", "5492", "5398.8" #else "6286", "6288.1", "6284.1", "6238", "6223.2", "6175", "6162", "6147.1", "6049", "6043.1", "6022", "5891.5", "5805.18", "5812", "5733", "5454.21", "5492", "5359.8", "5398.8", "4278.1" #end ]; @@ -24,7 +24,6 @@ class Main { private var currentIndex:Int; private var currentProgram:GLProgram; private var currentTime:Float; - private var lime:Lime; private var mouseUniform:GLUniformLocation; private var positionAttribute:Int; private var resolutionUniform:GLUniformLocation; @@ -34,7 +33,11 @@ class Main { private var vertexPosition:Int; - public function new () {} + public function new () { + + super (); + + } private function compile ():Void { @@ -116,6 +119,31 @@ class Main { } + public override function init (context:RenderContext):Void { + + switch (context) { + + case OPENGL (gl): + + fragmentShaders = randomizeArray (fragmentShaders); + currentIndex = 0; + + 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.bindBuffer (gl.ARRAY_BUFFER, null); + + compile (); + + default: + + // not implemented + + } + + } + + private function randomizeArray (array:Array):Array { var arrayCopy = array.copy (); @@ -133,51 +161,46 @@ class Main { } - public function ready (lime:Lime) { + public override function render (context:RenderContext):Void { - this.lime = lime; + switch (context) { + + case OPENGL (gl): + + if (currentProgram == null) return; + + currentTime = Timer.stamp () - startTime; + + gl.viewport (0, 0, window.width, window.height); + gl.useProgram (currentProgram); + + gl.uniform1f (timeUniform, currentTime); + gl.uniform2f (mouseUniform, 0.1, 0.1); //GL.uniform2f (mouseUniform, (stage.mouseX / stage.stageWidth) * 2 - 1, (stage.mouseY / stage.stageHeight) * 2 - 1); + gl.uniform2f (resolutionUniform, window.width, window.height); + gl.uniform1i (backbufferUniform, 0 ); + gl.uniform2f (surfaceSizeUniform, window.width, window.height); + + gl.bindBuffer (gl.ARRAY_BUFFER, buffer); + gl.vertexAttribPointer (positionAttribute, 2, gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer (vertexPosition, 2, gl.FLOAT, false, 0, 0); + + gl.clearColor (0, 0, 0, 1); + gl.clear (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT ); + gl.drawArrays (gl.TRIANGLES, 0, 6); + gl.bindBuffer (gl.ARRAY_BUFFER, null); + + default: + + // not implemented + + } - fragmentShaders = randomizeArray (fragmentShaders); - currentIndex = 0; - 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.bindBuffer (GL.ARRAY_BUFFER, null); - - compile (); } - public function render ():Void { - - if (currentProgram == null) return; - - currentTime = Timer.stamp () - startTime; - - GL.viewport (0, 0, lime.config.width, lime.config.height); - GL.useProgram (currentProgram); - - GL.uniform1f (timeUniform, currentTime); - GL.uniform2f (mouseUniform, 0.1, 0.1); //GL.uniform2f (mouseUniform, (stage.mouseX / stage.stageWidth) * 2 - 1, (stage.mouseY / stage.stageHeight) * 2 - 1); - GL.uniform2f (resolutionUniform, lime.config.width, lime.config.height); - GL.uniform1i (backbufferUniform, 0 ); - GL.uniform2f (surfaceSizeUniform, lime.config.width, lime.config.height); - - GL.bindBuffer (GL.ARRAY_BUFFER, buffer); - GL.vertexAttribPointer (positionAttribute, 2, GL.FLOAT, false, 0, 0); - GL.vertexAttribPointer (vertexPosition, 2, GL.FLOAT, false, 0, 0); - - GL.clearColor (0, 0, 0, 1); - GL.clear (GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT ); - GL.drawArrays (GL.TRIANGLES, 0, 6); - GL.bindBuffer (GL.ARRAY_BUFFER, null); - - } - - - public function update ():Void { + public override function update (deltaTime:Int):Void { if (currentTime > maxTime && fragmentShaders.length > 1) { diff --git a/samples/HerokuShaders/project.lime b/samples/HerokuShaders/project.lime deleted file mode 100644 index 3d89f41cd..000000000 --- a/samples/HerokuShaders/project.lime +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/samples/HerokuShaders/project.xml b/samples/HerokuShaders/project.xml new file mode 100644 index 000000000..ed13c45f6 --- /dev/null +++ b/samples/HerokuShaders/project.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SimpleAudioExample/Assets/ambience.ogg b/samples/SimpleAudio/Assets/ambience.ogg similarity index 100% rename from samples/SimpleAudioExample/Assets/ambience.ogg rename to samples/SimpleAudio/Assets/ambience.ogg diff --git a/samples/SimpleAudioExample/Assets/sound_licenses.txt b/samples/SimpleAudio/Assets/license.txt similarity index 100% rename from samples/SimpleAudioExample/Assets/sound_licenses.txt rename to samples/SimpleAudio/Assets/license.txt diff --git a/samples/SimpleAudioExample/Assets/sound.ogg b/samples/SimpleAudio/Assets/sound.ogg similarity index 100% rename from samples/SimpleAudioExample/Assets/sound.ogg rename to samples/SimpleAudio/Assets/sound.ogg diff --git a/samples/SimpleAudioExample/Assets/sound.wav b/samples/SimpleAudio/Assets/sound.wav similarity index 100% rename from samples/SimpleAudioExample/Assets/sound.wav rename to samples/SimpleAudio/Assets/sound.wav diff --git a/samples/SimpleOpenGL/SimpleOpenGLView.hxproj b/samples/SimpleAudio/SimpleAudio.hxproj similarity index 74% rename from samples/SimpleOpenGL/SimpleOpenGLView.hxproj rename to samples/SimpleAudio/SimpleAudio.hxproj index 789136620..7c57645fe 100644 --- a/samples/SimpleOpenGL/SimpleOpenGLView.hxproj +++ b/samples/SimpleAudio/SimpleAudio.hxproj @@ -4,30 +4,33 @@ - + - + + + - - + @@ -39,7 +42,7 @@ - + diff --git a/samples/SimpleAudio/Source/Main.hx b/samples/SimpleAudio/Source/Main.hx new file mode 100644 index 000000000..7cd25784f --- /dev/null +++ b/samples/SimpleAudio/Source/Main.hx @@ -0,0 +1,74 @@ +package; + + +import lime.app.Application; +import lime.audio.AudioSource; +import lime.graphics.RenderContext; +import lime.Assets; + + +class Main extends Application { + + + private var ambience:AudioSource; + private var sound:AudioSource; + + + public function new () { + + super (); + + } + + + public override function init (_):Void { + + #if !flash + ambience = new AudioSource (Assets.getAudioBuffer ("assets/ambience.ogg")); + ambience.play (); + #end + + sound = new AudioSource (Assets.getAudioBuffer ("assets/sound.wav")); + + } + + + public override function onMouseDown (_, _, _):Void { + + sound.play (); + + } + + + public override function render (context:RenderContext):Void { + + switch (context) { + + case CANVAS (context): + + context.fillStyle = "#3CB878"; + context.fillRect (0, 0, window.width, window.height); + + case DOM (element): + + element.style.backgroundColor = "#3CB878"; + + case FLASH (sprite): + + sprite.graphics.beginFill (0x3CB878); + sprite.graphics.drawRect (0, 0, window.width, window.height); + + case OPENGL (gl): + + gl.viewport (0, 0, window.width, window.height); + gl.clearColor (60 / 255, 184 / 255, 7 / 255, 1); + gl.clear (gl.COLOR_BUFFER_BIT); + + default: + + } + + } + + +} \ No newline at end of file diff --git a/samples/SimpleAudio/project.xml b/samples/SimpleAudio/project.xml new file mode 100644 index 000000000..5a597b586 --- /dev/null +++ b/samples/SimpleAudio/project.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/SimpleAudioExample/Assets/.keep b/samples/SimpleAudioExample/Assets/.keep deleted file mode 100644 index e69de29bb..000000000 diff --git a/samples/SimpleAudioExample/project.lime.xml b/samples/SimpleAudioExample/project.lime.xml deleted file mode 100644 index ec91cd58e..000000000 --- a/samples/SimpleAudioExample/project.lime.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/SimpleAudioExample/src/Main.hx b/samples/SimpleAudioExample/src/Main.hx deleted file mode 100644 index 34f0948f2..000000000 --- a/samples/SimpleAudioExample/src/Main.hx +++ /dev/null @@ -1,106 +0,0 @@ - - //Ported and modified from OpenFL samples - //underscorediscovery - -import lime.helpers.AudioHelper.Sound; -import lime.utils.Assets; -import lime.Lime; - - //Import GL stuff from lime -import lime.gl.GL; - -//Press any key to reset the music -//Click to play a sound - -class Main { - - public var lib : Lime; - - //Some value to mess with the clear color - private var red_value : Float = 1.0; - private var red_direction : Int = 1; - private var dt : Float = 0.016; - private var end_dt : Float = 0; - - public function new() { } - - public function ready( _lime : Lime ) { - - //Store a reference - lib = _lime; - - // Init the shaders and view - init(); - - } //ready - - - public function init() { - - lib.audio.create('music', 'assets/ambience.ogg', true ); - lib.audio.create('sound', 'assets/sound.ogg', false); - lib.audio.create('sound_wav', 'assets/sound.wav', false); - - lib.audio.play('music', 5); - lib.audio.sound('music').on_complete( function(sound:Sound){ - trace("music complete!"); - }); - - } //init - - //Called each frame by lime for logic (called before render) - public function update() { - - dt = haxe.Timer.stamp() - end_dt; - end_dt = haxe.Timer.stamp(); - - //an awful magic number to change the value slowly - red_value += (red_direction * 0.3) * dt; - - if(red_value >= 1) { - red_value = 1; - red_direction = -red_direction; - } else if(red_value <= 0) { - red_value = 0; - red_direction = -red_direction; - } - - } //update - - //Called by lime - public function onmousemove(_event:Dynamic) { - } - //Called by lime - public function onmousedown(_event:Dynamic) { - lib.audio.play('sound', 0.0); - } - //Called by lime - public function onmouseup(_event:Dynamic) { - } - //Called by lime - public function onkeydown(_event:Dynamic) { - lib.audio.position('music', 0.0); - } - //Called by lime - public function onkeyup(_event:Dynamic) { - } - - - //Called by lime - public function render() { - - //Set the viewport for GL - GL.viewport( 0, 0, lib.config.width, lib.config.height ); - - //Set the clear color to a weird color that bounces around - GL.clearColor( red_value, red_value*0.5, red_value*0.3, 1); - //Clear the buffers - GL.clear( GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT ); - - - } //render - - -} //Main - - diff --git a/samples/SimpleOpenGL/Assets/lime.png b/samples/SimpleOpenGL/Assets/lime.png deleted file mode 100644 index 5afb8060ba8dab0b09068cb169f40ac14143817a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41090 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�UTcQUL(p@u%T{Gyo)3%1Vl9c&?oJ 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 diff --git a/samples/SimpleOpenGL/Assets/lime.svg b/samples/SimpleOpenGL/Assets/lime.svg deleted file mode 100644 index 0e20a1c77..000000000 --- a/samples/SimpleOpenGL/Assets/lime.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/SimpleOpenGL/Source/Main.hx b/samples/SimpleOpenGL/Source/Main.hx deleted file mode 100644 index 9779f0435..000000000 --- a/samples/SimpleOpenGL/Source/Main.hx +++ /dev/null @@ -1,320 +0,0 @@ -package; - - -import format.png.Reader; -import format.png.Tools; -import haxe.io.Bytes; -import haxe.io.BytesData; -import haxe.io.BytesInput; -import lime.gl.GL; -import lime.gl.GLBuffer; -import lime.gl.GLProgram; -import lime.gl.GLTexture; -import lime.gl.GLUniformLocation; -import lime.utils.ByteArray; -import lime.utils.Matrix3D; -import lime.utils.Assets; -import lime.utils.Float32Array; -import lime.utils.UInt8Array; -import lime.Lime; - - -class Main { - - - private var imageData:UInt8Array; - private var imageHeight:Int; - private var imageWidth:Int; - private var imageUniform:GLUniformLocation; - private var lime:Lime; - private var modelViewMatrixUniform:GLUniformLocation; - private var projectionMatrixUniform:GLUniformLocation; - private var shaderProgram:GLProgram; - private var texCoordAttribute:Int; - private var texCoordBuffer:GLBuffer; - private var texture:GLTexture; - private var vertexAttribute:Int; - private var vertexBuffer:GLBuffer; - - - public function new () {} - - - private function createBuffers ():Void { - - var vertices = [ - - imageWidth, imageHeight, 0, - 0, imageHeight, 0, - imageWidth, 0, 0, - 0, 0, 0 - - ]; - - vertexBuffer = GL.createBuffer (); - GL.bindBuffer (GL.ARRAY_BUFFER, vertexBuffer); - GL.bufferData (GL.ARRAY_BUFFER, new Float32Array (cast vertices), GL.STATIC_DRAW); - GL.bindBuffer (GL.ARRAY_BUFFER, null); - - var texCoords = [ - - 1, 1, - 0, 1, - 1, 0, - 0, 0, - - ]; - - texCoordBuffer = GL.createBuffer (); - GL.bindBuffer (GL.ARRAY_BUFFER, texCoordBuffer); - GL.bufferData (GL.ARRAY_BUFFER, new Float32Array (cast texCoords), GL.STATIC_DRAW); - GL.bindBuffer (GL.ARRAY_BUFFER, null); - - } - - - private function createTexture ():Void { - - texture = GL.createTexture (); - GL.bindTexture (GL.TEXTURE_2D, texture); - GL.texImage2D (GL.TEXTURE_2D, 0, GL.RGBA, imageHeight, imageHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, imageData); - GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR); - GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR); - GL.bindTexture (GL.TEXTURE_2D, null); - - } - - - private function initializeShaders ():Void { - - var vertexShaderSource = ""; - - #if lime_html5 - vertexShaderSource += "precision mediump float;"; - #end - - vertexShaderSource += "attribute vec3 aVertexPosition; - attribute vec2 aTexCoord; - varying vec2 vTexCoord; - - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; - - void main(void) { - vTexCoord = aTexCoord; - gl_Position = uProjectionMatrix * uModelViewMatrix * vec4 (aVertexPosition, 1.0); - }"; - - var vertexShader = GL.createShader (GL.VERTEX_SHADER); - GL.shaderSource (vertexShader, vertexShaderSource); - GL.compileShader (vertexShader); - - if (GL.getShaderParameter (vertexShader, GL.COMPILE_STATUS) == 0) { - - throw "Error compiling vertex shader"; - - } - - var fragmentShaderSource = ""; - - #if lime_html5 - fragmentShaderSource += "precision mediump float;"; - #end - - fragmentShaderSource += - "varying vec2 vTexCoord; - uniform sampler2D uImage0; - - void main(void) - { - gl_FragColor = texture2D (uImage0, vTexCoord); - }"; - - var fragmentShader = GL.createShader (GL.FRAGMENT_SHADER); - GL.shaderSource (fragmentShader, fragmentShaderSource); - GL.compileShader (fragmentShader); - - if (GL.getShaderParameter (fragmentShader, GL.COMPILE_STATUS) == 0) { - - throw "Error compiling fragment shader"; - - } - - shaderProgram = GL.createProgram (); - GL.attachShader (shaderProgram, vertexShader); - GL.attachShader (shaderProgram, fragmentShader); - GL.linkProgram (shaderProgram); - - if (GL.getProgramParameter (shaderProgram, GL.LINK_STATUS) == 0) { - - throw "Unable to initialize the shader program."; - - } - - vertexAttribute = GL.getAttribLocation (shaderProgram, "aVertexPosition"); - texCoordAttribute = GL.getAttribLocation (shaderProgram, "aTexCoord"); - projectionMatrixUniform = GL.getUniformLocation (shaderProgram, "uProjectionMatrix"); - modelViewMatrixUniform = GL.getUniformLocation (shaderProgram, "uModelViewMatrix"); - imageUniform = GL.getUniformLocation (shaderProgram, "uImage0"); - - } - - -#if lime_html5 - - function load_image(_id:String, onload:Void->Void) { - - var image: js.html.ImageElement = js.Browser.document.createImageElement(); - - image.onload = function(a) { - - try { - - var tmp_canvas = js.Browser.document.createCanvasElement(); - tmp_canvas.width = image.width; - tmp_canvas.height = image.height; - - var tmp_context = tmp_canvas.getContext2d(); - tmp_context.clearRect( 0,0, tmp_canvas.width, tmp_canvas.height ); - tmp_context.drawImage( image, 0, 0, image.width, image.height ); - - var image_bytes = tmp_context.getImageData( 0, 0, tmp_canvas.width, tmp_canvas.height ); - var haxe_bytes = new lime.utils.UInt8Array( image_bytes.data ); - - imageData = haxe_bytes; - imageHeight = image.width; - imageWidth = image.height; - - tmp_canvas = null; - tmp_context = null; - haxe_bytes = null; - image_bytes = null; - - onload(); - - } catch(e:Dynamic) { - - trace(e); - var tips = '- textures might require power of two sizes\n'; - tips += '- textures served from file:/// throw security errors\n'; - tips += '- textures served over http:// work for cross origin'; - - trace(tips); - throw e; - - } - - } //image.onload - - //source comes after the onload being set, for race conditions - image.src = _id; - - } //load_html5_image - -#else - - function load_image(_id:String, onload:Void->Void) { - - var bytes : ByteArray = Assets.getBytes (_id); - var byteInput = new BytesInput ( bytes, 0, bytes.length); - var png = new Reader (byteInput).read (); - var data = Tools.extract32 (png); - var header = Tools.getHeader (png); - - imageWidth = header.width; - imageHeight = header.height; - imageData = new UInt8Array (data.getData ()); - - var image_length = imageWidth * imageHeight; - - //bytes are returned in a different order, bgra - //so we swap back to rgba - for(i in 0 ... image_length) { - - var b = imageData[i*4+0]; - var g = imageData[i*4+1]; - var r = imageData[i*4+2]; - var a = imageData[i*4+3]; - - imageData[i*4+0] = r; - imageData[i*4+1] = g; - imageData[i*4+2] = b; - imageData[i*4+3] = a; - - } - - onload(); - - } - -#end //!lime_html5 - - var loaded = false; - - public function ready (lime:Lime):Void { - - this.lime = lime; - - //we load the image with a callback, - //because on html5 it is asynchronous and we want - //to only try and use it when it's done loading - load_image("assets/lime.png", function(){ - - initializeShaders (); - - createBuffers (); - createTexture (); - - loaded = true; - - }); - - } - - - private function render ():Void { - - if(!loaded) { - return; - } - - GL.viewport (0, 0, lime.config.width, lime.config.height); - - GL.clearColor (1.0, 1.0, 1.0, 1.0); - GL.clear (GL.COLOR_BUFFER_BIT); - - var positionX = (lime.config.width - imageWidth) / 2; - var positionY = (lime.config.height - imageHeight) / 2; - - var projectionMatrix = Matrix3D.createOrtho (0, lime.config.width, lime.config.height, 0, 1000, -1000); - var modelViewMatrix = Matrix3D.create2D (positionX, positionY, 1, 0); - - GL.useProgram (shaderProgram); - GL.enableVertexAttribArray (vertexAttribute); - GL.enableVertexAttribArray (texCoordAttribute); - - GL.activeTexture (GL.TEXTURE0); - GL.bindTexture (GL.TEXTURE_2D, texture); - - GL.bindBuffer (GL.ARRAY_BUFFER, vertexBuffer); - GL.vertexAttribPointer (vertexAttribute, 3, GL.FLOAT, false, 0, 0); - GL.bindBuffer (GL.ARRAY_BUFFER, texCoordBuffer); - GL.vertexAttribPointer (texCoordAttribute, 2, GL.FLOAT, false, 0, 0); - - GL.uniformMatrix3D (projectionMatrixUniform, false, projectionMatrix); - GL.uniformMatrix3D (modelViewMatrixUniform, false, modelViewMatrix); - GL.uniform1i (imageUniform, 0); - - GL.drawArrays (GL.TRIANGLE_STRIP, 0, 4); - - GL.bindBuffer (GL.ARRAY_BUFFER, null); - GL.bindTexture (GL.TEXTURE_2D, null); - - GL.disableVertexAttribArray (vertexAttribute); - GL.disableVertexAttribArray (texCoordAttribute); - GL.useProgram (null); - - } - - -} diff --git a/samples/SimpleOpenGL/project.lime b/samples/SimpleOpenGL/project.lime deleted file mode 100644 index 10e2b868e..000000000 --- a/samples/SimpleOpenGL/project.lime +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - -