1"use strict" 2 3//============================================================================== 4// 5// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 6// 7// piCamera 8// 9//============================================================================== 10 11function piCamera() 12{ 13 var mMatrix = setIdentity(); 14 var mMatrixInv = setIdentity(); 15 16 var mPosition = [0.0,0.0,0.0]; 17 var mXRotation = 0.0; 18 var mYRotation = 0.0; 19 20 var mPositionTarget = [0.0,0.0,0.0]; 21 var mXRotationTarget = 0.0; 22 var mYRotationTarget = 0.0; 23 24 var me = {}; 25 26 me.SetPos = function(pos) 27 { 28 mPosition = pos; 29 }; 30 31 me.LocalMove = function( dis ) 32 { 33 dis = matMulvec( setRotationY(-mYRotation), dis); 34 mPositionTarget = sub(mPositionTarget,dis) 35 }; 36 37 me.RotateXY = function( x, y) 38 { 39 mXRotationTarget -= x; 40 mYRotationTarget -= y; 41 mXRotationTarget = Math.min( Math.max( mXRotationTarget, -Math.PI/2), Math.PI/2 ); 42 }; 43 44 45 me.CameraExectue = function( dt ) 46 { 47 // smooth position 48 mXRotation += (mXRotationTarget-mXRotation) * 12.0*dt; 49 mYRotation += (mYRotationTarget-mYRotation) * 12.0*dt; 50 mPosition = add(mPosition, mul( sub(mPositionTarget, mPosition), 12.0*dt)); 51 52 // Make Camera matrix 53 mMatrix = matMul( matMul(setRotationX(mXRotation), 54 setRotationY(mYRotation)), 55 setTranslation(mPosition)); 56 mMatrixInv = invertFast(mMatrix); 57 58 } 59 60 me.GetMatrix = function() { return mMatrix; }; 61 me.GetMatrixInverse = function() { return mMatrixInv; }; 62 me.SetMatrix = function( mat ) 63 { 64 mMatrix = mat; 65 mMatrixInv = invertFast(mMatrix); 66 67 mPosition = getXYZ(matMulpoint(mat, [0.0,0.0,0.0])); 68 mPositionTarget = mPosition; 69 }; 70 71 me.GetPos = function() { return getXYZ(matMulpoint(mMatrixInv, [0.0,0.0,0.0])); } 72 me.GetDir = function() { return getXYZ(normalize(matMulvec(mMatrixInv, [0.0,0.0,-1.0]))); } 73 74 return me; 75} 76//============================================================================== 77// 78// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 79// 80// piFile 81// 82//============================================================================== 83 84function piFile( binaryDataArrayBuffer ) 85{ 86 // private 87 var mDataView = binaryDataArrayBuffer; 88 var mOffset = 0; 89 90 // public members 91 var me = {}; 92 me.mDummy = 0; 93 94 me.Seek = function( off ) { mOffset = off; }; 95 me.ReadUInt8 = function() { var res = (new Uint8Array(mDataView,mOffset))[0]; mOffset+=1; return res; }; 96 me.ReadUInt16 = function() { var res = (new Uint16Array(mDataView,mOffset))[0]; mOffset+=2; return res; }; 97 me.ReadUInt32 = function() { var res = (new Uint32Array(mDataView,mOffset))[0]; mOffset+=4; return res; }; 98 me.ReadUInt64 = function() { return me.ReadUInt32() + (me.ReadUInt32()<<32); }; 99 me.ReadFloat32 = function() { var res = (new Float32Array(mDataView,mOffset))[0]; mOffset+=4; return res; }; 100 me.ReadFloat32Array = function(n) 101 { 102 var src = new Float32Array(mDataView, mOffset); 103 var res = []; for( var i=0; i<n; i++ ) { res[i] = src[i]; } 104 mOffset += 4*n; 105 return res; 106 }; 107 me.ReadFloat32ArrayNative = function(n) { var src = new Float32Array(mDataView, mOffset); mOffset += 4*n; return src; }; 108 return me; 109} 110//============================================================================== 111// 112// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 113// 114// piMesh 115// 116//============================================================================== 117 118function piMesh() 119{ 120 this.mChunks = []; 121 this.mPrimitiveType = 0; 122 this.mVertexFormat = null; 123} 124 125piMesh.prototype.createCube = function(renderer) 126{ 127 this.mPrimitiveType = 0; 128 129 this.mChunks[0] = { mVerts : new Float32Array([ -1.0, -1.0, -1.0, 130 1.0, -1.0, -1.0, 131 -1.0, 1.0, -1.0, 132 1.0, 1.0, -1.0, 133 -1.0, -1.0, 1.0, 134 1.0, -1.0, 1.0, 135 -1.0, 1.0, 1.0, 136 1.0, 1.0, 1.0 ]), 137 138 mIndices : new Uint16Array([ 0, 2, 1, 1, 2, 3, 5, 1, 3, 5, 3, 7, 4, 5, 7, 4, 7, 6, 4, 6, 2, 4, 2, 0, 6, 7, 3, 6, 3, 2, 4, 0, 1, 4, 1, 5 ]), 139 mNumVertices : 8, 140 mNumFaces : 12, 141 mTransform : setIdentity(), 142 mVBO : null, 143 mIBO : null }; 144 145 this.mVertexFormat = { mStride:12, mChannels:[ { mNumComponents:3, mType: renderer.TYPE.FLOAT32, mNormalize: false } ] }; 146 147 return true; 148} 149 150piMesh.prototype.createCubeSharp = function (renderer) 151{ 152 this.mPrimitiveType = 0; 153 154 this.mChunks[0] = { mVerts : new Float32Array([-1.0, 1.0,-1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 155 -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 156 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 157 1.0, 1.0,-1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 158 159 -1.0,-1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 160 1.0,-1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 161 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 162 -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 163 164 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 165 1.0,-1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 166 1.0,-1.0,-1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 167 1.0, 1.0,-1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 168 169 1.0,-1.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0, 170 -1.0,-1.0,-1.0, 0.0, 0.0,-1.0, 0.0, 1.0, 171 -1.0, 1.0,-1.0, 0.0, 0.0,-1.0, 1.0, 1.0, 172 1.0, 1.0,-1.0, 0.0, 0.0,-1.0, 1.0, 0.0, 173 174 -1.0,-1.0, 1.0, 0.0,-1.0, 0.0, 0.0, 0.0, 175 -1.0,-1.0,-1.0, 0.0,-1.0, 0.0, 0.0, 1.0, 176 1.0,-1.0,-1.0, 0.0,-1.0, 0.0, 1.0, 1.0, 177 1.0,-1.0, 1.0, 0.0,-1.0, 0.0, 1.0, 0.0, 178 179 -1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 180 -1.0, 1.0,-1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 181 -1.0,-1.0,-1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 182 -1.0,-1.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0 ]), 183 184 mIndices : new Uint16Array([0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10,8,10,11, 12,13,14,12,14,15, 16,17,18,16,18,19, 20,21,22,20,22,23]), 185 mNumVertices : 24, 186 mNumFaces : 12, 187 mTransform : setIdentity(), 188 mVBO : null, 189 mIBO : null }; 190 191 192 this.mVertexFormat = { mStride:32, mChannels:[ { mNumComponents:3, mType: renderer.TYPE.FLOAT32, mNormalize: false }, 193 { mNumComponents:3, mType: renderer.TYPE.FLOAT32, mNormalize: false }, 194 { mNumComponents:2, mType: renderer.TYPE.FLOAT32, mNormalize: false } ] }; 195 196 return true; 197} 198 199 200piMesh.prototype.createUnitQuad = function (renderer) 201{ 202 this.mPrimitiveType = 0; 203 this.mVertexFormat = { mStride:8, mChannels: [ {mNumComponents:2, mType: renderer.TYPE.FLOAT32, mNormalize: false} ] }; 204 205 this.mChunks[0] = { mVerts : new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]), 206 mIndices : new Uint16Array([0, 2, 1, 1, 2, 3]), 207 mNumVertices : 4, 208 mNumFaces : 2, 209 mTransform : setIdentity(), 210 mVBO : null, 211 mIBO : null }; 212 213 return true; 214} 215 216 217 218 219piMesh.prototype.destroy = function() 220{ } 221 222piMesh.prototype.scale = function (x, y, z) 223{ 224 var stride = this.mVertexFormat.mStride/4; 225 for( var j=0; j<this.mChunks.length; j++ ) 226 { 227 var nv = this.mChunks[j].mNumVertices; 228 for (var i = 0; i < nv; i++) 229 { 230 this.mChunks[j].mVerts[stride * i + 0] *= x; 231 this.mChunks[j].mVerts[stride * i + 1] *= y; 232 this.mChunks[j].mVerts[stride * i + 2] *= z; 233 } 234 } 235} 236 237piMesh.prototype.translate = function (x, y, z) 238{ 239 var stride = this.mVertexFormat.mStride/4; 240 for( var j=0; j<this.mChunks.length; j++ ) 241 { 242 var nv = this.mChunks[j].mNumVertices; 243 for (var i = 0; i < nv; i++) 244 { 245 this.mChunks[j].mVerts[stride * i + 0] += x; 246 this.mChunks[j].mVerts[stride * i + 1] += y; 247 this.mChunks[j].mVerts[stride * i + 2] += z; 248 } 249 } 250} 251 252piMesh.prototype.GPULoad = function (renderer) 253{ 254 for( var i=0; i<this.mChunks.length; i++ ) 255 { 256 var vbo = renderer.CreateVertexArray(this.mChunks[i].mVerts, renderer.BUFTYPE.STATIC ); 257 if (vbo == null) 258 return false; 259 260 var ibo = renderer.CreateIndexArray(this.mChunks[i].mIndices, renderer.BUFTYPE.STATIC); 261 if (ibo == null) 262 return false; 263 264 this.mChunks[i].mVBO = vbo; 265 this.mChunks[i].mIBO = ibo; 266 } 267 return true; 268} 269 270piMesh.prototype.GPURender = function (renderer, positions )//, matPrj, matCam ) 271{ 272 var num = this.mChunks.length; 273 for( var i=0; i<num; i++ ) 274 { 275 renderer.AttachVertexArray(this.mChunks[i].mVBO, this.mVertexFormat, positions ); 276 renderer.AttachIndexArray(this.mChunks[i].mIBO ); 277 renderer.DrawPrimitive(renderer.PRIMTYPE.TRIANGLES, this.mChunks[i].mNumFaces * 3, true, 1); 278 renderer.DetachIndexArray(this.mChunks[i].mIBO); 279 renderer.DetachVertexArray(this.mChunks[i].mVBO, this.mVertexFormat ); 280 } 281} 282//============================================================================== 283// 284// piLibs 2014-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 285// 286// piRenderer 287// 288//============================================================================== 289 290function piRenderer() 291{ 292 // private members 293 294 var mGL = null; 295 var mBindedShader = null; 296 var mIs20 = false; 297 var mFloat32Textures; 298 var mFloat32Filter; 299 var mFloat16Textures; 300 var mDrawBuffers; 301 var mDepthTextures; 302 var mDerivatives; 303 var mFloat16Filter; 304 var mShaderTextureLOD; 305 var mAnisotropic; 306 var mRenderToFloat32F; 307 var mDebugShader; 308 var mAsynchCompile; 309 310 var mVBO_Quad = null; 311 var mVBO_Tri = null; 312 var mVBO_CubePosNor = null; 313 var mVBO_CubePos = null; 314 var mShaderHeader = ["",""]; 315 var mShaderHeaderLines = [0,0]; 316 317 // public members 318 var me = {}; 319 320 me.CLEAR = { Color: 1, Zbuffer : 2, Stencil : 4 }; 321 me.TEXFMT = { C4I8 : 0, C1I8 : 1, C1F16 : 2, C4F16 : 3, C1F32 : 4, C4F32 : 5, Z16 : 6, Z24 : 7, Z32 : 8, C3F32:9 }; 322 me.TEXWRP = { CLAMP : 0, REPEAT : 1 }; 323 me.BUFTYPE = { STATIC : 0, DYNAMIC : 1 }; 324 me.PRIMTYPE = { POINTS : 0, LINES : 1, LINE_LOOP : 2, LINE_STRIP : 3, TRIANGLES : 4, TRIANGLE_STRIP : 5 };
325 me.RENDSTGATE = { WIREFRAME : 0, FRONT_FACE : 1, CULL_FACE : 2, DEPTH_TEST : 3, ALPHA_TO_COVERAGE : 4 }; 326 me.TEXTYPE = { T2D : 0, T3D : 1, CUBEMAP : 2 }; 327 me.FILTER = { NONE : 0, LINEAR : 1, MIPMAP : 2, NONE_MIPMAP : 3 }; 328 me.TYPE = { UINT8 : 0, UINT16 : 1, UINT32 : 2, FLOAT16: 3, FLOAT32 : 4, FLOAT64: 5 }; 329 330 // private functions 331 332 var iFormatPI2GL = function( format ) 333 { 334 if( mIs20 ) 335 { 336 if (format === me.TEXFMT.C4I8) return { mGLFormat: mGL.RGBA8, mGLExternal: mGL.RGBA, mGLType: mGL.UNSIGNED_BYTE } 337 else if (format === me.TEXFMT.C1I8) return { mGLFormat: mGL.R8, mGLExternal: mGL.RED, mGLType: mGL.UNSIGNED_BYTE } 338 else if (format === me.TEXFMT.C1F16) return { mGLFormat: mGL.R16F, mGLExternal: mGL.RED, mGLType: mGL.FLOAT } 339 else if (format === me.TEXFMT.C4F16) return { mGLFormat: mGL.RGBA16F, mGLExternal: mGL.RGBA, mGLType: mGL.FLOAT } 340 else if (format === me.TEXFMT.C1F32) return { mGLFormat: mGL.R32F, mGLExternal: mGL.RED, mGLType: mGL.FLOAT } 341 else if (format === me.TEXFMT.C4F32) return { mGLFormat: mGL.RGBA32F, mGLExternal: mGL.RGBA, mGLType: mGL.FLOAT } 342 else if (format === me.TEXFMT.C3F32) return { mGLFormat: mGL.RGB32F, mGLExternal: mGL.RGB, mGLType: mGL.FLOAT } 343 else if (format === me.TEXFMT.Z16) return { mGLFormat: mGL.DEPTH_COMPONENT16, mGLExternal: mGL.DEPTH_COMPONENT, mGLType: mGL.UNSIGNED_SHORT } 344 else if (format === me.TEXFMT.Z24) return { mGLFormat: mGL.DEPTH_COMPONENT24, mGLExternal: mGL.DEPTH_COMPONENT, mGLType: mGL.UNSIGNED_SHORT } 345 else if (format === me.TEXFMT.Z32) return { mGLFormat: mGL.DEPTH_COMPONENT32F, mGLExternal: mGL.DEPTH_COMPONENT, mGLType: mGL.UNSIGNED_SHORT } 346 } 347 else 348 { 349 if (format === me.TEXFMT.C4I8) return { mGLFormat: mGL.RGBA, mGLExternal: mGL.RGBA, mGLType: mGL.UNSIGNED_BYTE } 350 else if (format === me.TEXFMT.C1I8) return { mGLFormat: mGL.LUMINANCE, mGLExternal: mGL.LUMINANCE, mGLType: mGL.UNSIGNED_BYTE } 351 else if (format === me.TEXFMT.C1F16) return { mGLFormat: mGL.LUMINANCE, mGLExternal: mGL.LUMINANCE, mGLType: mGL.FLOAT } 352 else if (format === me.TEXFMT.C4F16) return { mGLFormat: mGL.RGBA, mGLExternal: mGL.RGBA, mGLType: mGL.FLOAT } 353 else if (format === me.TEXFMT.C1F32) return { mGLFormat: mGL.LUMINANCE, mGLExternal: mGL.RED, mGLType: mGL.FLOAT } 354 else if (format === me.TEXFMT.C4F32) return { mGLFormat: mGL.RGBA, mGLExternal: mGL.RGBA, mGLType: mGL.FLOAT } 355 else if (format === me.TEXFMT.Z16) return { mGLFormat: mGL.DEPTH_COMPONENT, mGLExternal: mGL.DEPTH_COMPONENT, mGLType: mGL.UNSIGNED_SHORT } 356 } 357 358 return null; 359 } 360 361 // public functions 362 363 me.Initialize = function( gl ) 364 { 365 mGL = gl; 366 367 mIs20 = !(gl instanceof WebGLRenderingContext); 368 369 if( mIs20 ) 370 { 371 mFloat32Textures = true; 372 mFloat32Filter = mGL.getExtension( 'OES_texture_float_linear'); 373 mFloat16Textures = true; 374 mFloat16Filter = mGL.getExtension( 'OES_texture_half_float_linear' ); 375 mDerivatives = true; 376 mDrawBuffers = true; 377 mDepthTextures = true; 378 mShaderTextureLOD = true; 379 mAnisotropic = mGL.getExtension( 'EXT_texture_filter_anisotropic' ); 380 mRenderToFloat32F = mGL.getExtension( 'EXT_color_buffer_float'); 381 mDebugShader = mGL.getExtension('WEBGL_debug_shaders'); 382 mAsynchCompile = mGL.getExtension('KHR_parallel_shader_compile'); 383 384 mGL.hint( mGL.FRAGMENT_SHADER_DERIVATIVE_HINT, mGL.NICEST); 385 } 386 else 387 { 388 mFloat32Textures = mGL.getExtension( 'OES_texture_float' ); 389 mFloat32Filter = mGL.getExtension( 'OES_texture_float_linear'); 390 mFloat16Textures = mGL.getExtension( 'OES_texture_half_float' ); 391 mFloat16Filter = mGL.getExtension( 'OES_texture_half_float_linear' ); 392 mDerivatives = mGL.getExtension( 'OES_standard_derivatives' ); 393 mDrawBuffers = mGL.getExtension( 'WEBGL_draw_buffers' ); 394 mDepthTextures = mGL.getExtension( 'WEBGL_depth_texture' ); 395 mShaderTextureLOD = mGL.getExtension( 'EXT_shader_texture_lod' ); 396 mAnisotropic = mGL.getExtension( 'EXT_texture_filter_anisotropic' ); 397 mRenderToFloat32F = mFloat32Textures; 398 mDebugShader = null; 399 mAsynchCompile = null; 400 401 if( mDerivatives !== null) mGL.hint( mDerivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES, mGL.NICEST); 402 } 403 404 405 var maxTexSize = mGL.getParameter( mGL.MAX_TEXTURE_SIZE ); 406 var maxCubeSize = mGL.getParameter( mGL.MAX_CUBE_MAP_TEXTURE_SIZE ); 407 var maxRenderbufferSize = mGL.getParameter( mGL.MAX_RENDERBUFFER_SIZE ); 408 var extensions = mGL.getSupportedExtensions(); 409 var textureUnits = mGL.getParameter( mGL.MAX_TEXTURE_IMAGE_UNITS ); 410 console.log("WebGL (2.0=" + mIs20 + "):" + 411 " Asynch Compile: " + ((mAsynchCompile !==null) ? "yes" : "no") + 412 ", Textures: F32 [" + ((mFloat32Textures !==null) ? "yes" : "no") + 413 "], F16 [" + ((mFloat16Textures !==null) ? "yes" : "no") + 414 "], Depth [" + ((mDepthTextures !==null) ? "yes" : "no") + 415 "], LOD [" + ((mShaderTextureLOD!==null) ? "yes" : "no") + 416 "], Aniso [" + ((mAnisotropic !==null) ? "yes" : "no") + 417 "], Units [" + textureUnits + 418 "], Max Size [" + maxTexSize + 419 "], Cube Max Size [" + maxCubeSize + 420 "], Targets: MRT [" + ((mDrawBuffers !==null) ? "yes" : "no") + 421 "], F32 [" + ((mRenderToFloat32F!==null) ? "yes" : "no") + 422 "], Max Size [" + maxRenderbufferSize + "]"); 423 424 // create a 2D quad Vertex Buffer 425 var vertices = 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] ); 426 mVBO_Quad = mGL.createBuffer(); 427 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_Quad ); 428 mGL.bufferData( mGL.ARRAY_BUFFER, vertices, mGL.STATIC_DRAW ); 429 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 430 431 // create a 2D triangle Vertex Buffer 432 mVBO_Tri = mGL.createBuffer(); 433 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_Tri ); 434 mGL.bufferData( mGL.ARRAY_BUFFER, new Float32Array( [ -1.0, -1.0, 3.0, -1.0, -1.0, 3.0] ), mGL.STATIC_DRAW ); 435 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 436 437 // create a 3D cube Vertex Buffer 438 mVBO_CubePosNor = mGL.createBuffer(); 439 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_CubePosNor ); 440 mGL.bufferData( mGL.ARRAY_BUFFER, new Float32Array( [ -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 441 -1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 442 -1.0, 1.0, -1.0, -1.0, 0.0, 0.0, 443 -1.0, 1.0, 1.0, -1.0, 0.0, 0.0, 444 1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 445 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 446 1.0, -1.0, -1.0, 1.0, 0.0, 0.0, 447 1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 448 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 449 1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 450 -1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 451 -1.0, 1.0, -1.0, 0.0, 1.0, 0.0, 452 1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 453 1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 454 -1.0, -1.0, -1.0, 0.0, -1.0, 0.0, 455 -1.0, -1.0, 1.0, 0.0, -1.0, 0.0, 456 -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 457 -1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 458 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 459 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 460 -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 461 -1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 462 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 463 1.0, 1.0, -1.0, 0.0, 0.0, -1.0 ] ), mGL.STATIC_DRAW ); 464 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 465 466 // create a 3D cube Vertex Buffer 467 mVBO_CubePos = mGL.createBuffer(); 468 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_CubePos ); 469 mGL.bufferData( mGL.ARRAY_BUFFER, new Float32Array( [ -1.0, -1.0, -1.0, 470 -1.0, -1.0, 1.0, 471 -1.0, 1.0, -1.0, 472 -1.0, 1.0, 1.0, 473 1.0, 1.0, -1.0, 474 1.0, 1.0, 1.0, 475 1.0, -1.0, -1.0, 476 1.0, -1.0, 1.0, 477 1.0, 1.0, 1.0, 478 1.0, 1.0, -1.0, 479 -1.0, 1.0, 1.0, 480 -1.0, 1.0, -1.0, 481 1.0, -1.0, -1.0, 482 1.0, -1.0, 1.0, 483 -1.0, -1.0, -1.0, 484 -1.0, -1.0, 1.0, 485 -1.0, 1.0, 1.0, 486 -1.0, -1.0, 1.0, 487 1.0, 1.0, 1.0, 488 1.0, -1.0, 1.0, 489 -1.0, -1.0, -1.0, 490 -1.0, 1.0, -1.0, 491 1.0, -1.0, -1.0, 492 1.0, 1.0, -1.0 ] ), mGL.STATIC_DRAW ); 493 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 494 495 //------------------------------------------------------------------- 496 497 mShaderHeader[0] = ""; 498 mShaderHeaderLines[0] = 0; 499 if( mIs20 ) 500 { 501 mShaderHeader[0] += "#version 300 es\n" + 502 "#ifdef GL_ES\n"+ 503 "precision highp float;\n" + 504 "precision highp int;\n"+ 505 "precision mediump sampler3D;\n"+ 506 "#endif\n"; 507 mShaderHeaderLines[0] += 6; 508 } 509 else 510 { 511 mShaderHeader[0] += "#ifdef GL_ES\n"+ 512 "precision highp float;\n" + 513 "precision highp int;\n"+ 514 "#endif\n"+
515 "float round( float x ) { return floor(x+0.5); }\n"+ 516 "vec2 round(vec2 x) { return floor(x + 0.5); }\n"+ 517 "vec3 round(vec3 x) { return floor(x + 0.5); }\n"+ 518 "vec4 round(vec4 x) { return floor(x + 0.5); }\n"+ 519 "float trunc( float x, float n ) { return floor(x*n)/n; }\n"+ 520 "mat3 transpose(mat3 m) { return mat3(m[0].x, m[1].x, m[2].x, m[0].y, m[1].y, m[2].y, m[0].z, m[1].z, m[2].z); }\n"+ 521 "float determinant( in mat2 m ) { return m[0][0]*m[1][1] - m[0][1]*m[1][0]; }\n"+ 522 "float determinant( mat4 m ) { float b00 = m[0][0] * m[1][1] - m[0][1] * m[1][0], b01 = m[0][0] * m[1][2] - m[0][2] * m[1][0], b02 = m[0][0] * m[1][3] - m[0][3] * m[1][0], b03 = m[0][1] * m[1][2] - m[0][2] * m[1][1], b04 = m[0][1] * m[1][3] - m[0][3] * m[1][1], b05 = m[0][2] * m[1][3] - m[0][3] * m[1][2], b06 = m[2][0] * m[3][1] - m[2][1] * m[3][0], b07 = m[2][0] * m[3][2] - m[2][2] * m[3][0], b08 = m[2][0] * m[3][3] - m[2][3] * m[3][0], b09 = m[2][1] * m[3][2] - m[2][2] * m[3][1], b10 = m[2][1] * m[3][3] - m[2][3] * m[3][1], b11 = m[2][2] * m[3][3] - m[2][3] * m[3][2]; return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;}\n"+ 523 "mat2 inverse(mat2 m) { float det = determinant(m); return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / det; }\n"+ 524 "mat4 inverse(mat4 m ) { float inv0 = m[1].y*m[2].z*m[3].w - m[1].y*m[2].w*m[3].z - m[2].y*m[1].z*m[3].w + m[2].y*m[1].w*m[3].z + m[3].y*m[1].z*m[2].w - m[3].y*m[1].w*m[2].z; float inv4 = -m[1].x*m[2].z*m[3].w + m[1].x*m[2].w*m[3].z + m[2].x*m[1].z*m[3].w - m[2].x*m[1].w*m[3].z - m[3].x*m[1].z*m[2].w + m[3].x*m[1].w*m[2].z; float inv8 = m[1].x*m[2].y*m[3].w - m[1].x*m[2].w*m[3].y - m[2].x * m[1].y * m[3].w + m[2].x * m[1].w * m[3].y + m[3].x * m[1].y * m[2].w - m[3].x * m[1].w * m[2].y; float inv12 = -m[1].x * m[2].y * m[3].z + m[1].x * m[2].z * m[3].y +m[2].x * m[1].y * m[3].z - m[2].x * m[1].z * m[3].y - m[3].x * m[1].y * m[2].z + m[3].x * m[1].z * m[2].y; float inv1 = -m[0].y*m[2].z * m[3].w + m[0].y*m[2].w * m[3].z + m[2].y * m[0].z * m[3].w - m[2].y * m[0].w * m[3].z - m[3].y * m[0].z * m[2].w + m[3].y * m[0].w * m[2].z; float inv5 = m[0].x * m[2].z * m[3].w - m[0].x * m[2].w * m[3].z - m[2].x * m[0].z * m[3].w + m[2].x * m[0].w * m[3].z + m[3].x * m[0].z * m[2].w - m[3].x * m[0].w * m[2].z; float inv9 = -m[0].x * m[2].y * m[3].w + m[0].x * m[2].w * m[3].y + m[2].x * m[0].y * m[3].w - m[2].x * m[0].w * m[3].y - m[3].x * m[0].y * m[2].w + m[3].x * m[0].w * m[2].y; float inv13 = m[0].x * m[2].y * m[3].z - m[0].x * m[2].z * m[3].y - m[2].x * m[0].y * m[3].z + m[2].x * m[0].z * m[3].y + m[3].x * m[0].y * m[2].z - m[3].x * m[0].z * m[2].y; float inv2 = m[0].y * m[1].z * m[3].w - m[0].y * m[1].w * m[3].z - m[1].y * m[0].z * m[3].w + m[1].y * m[0].w * m[3].z + m[3].y * m[0].z * m[1].w - m[3].y * m[0].w * m[1].z; float inv6 = -m[0].x * m[1].z * m[3].w + m[0].x * m[1].w * m[3].z + m[1].x * m[0].z * m[3].w - m[1].x * m[0].w * m[3].z - m[3].x * m[0].z * m[1].w + m[3].x * m[0].w * m[1].z; float inv10 = m[0].x * m[1].y * m[3].w - m[0].x * m[1].w * m[3].y - m[1].x * m[0].y * m[3].w + m[1].x * m[0].w * m[3].y + m[3].x * m[0].y * m[1].w - m[3].x * m[0].w * m[1].y; float inv14 = -m[0].x * m[1].y * m[3].z + m[0].x * m[1].z * m[3].y + m[1].x * m[0].y * m[3].z - m[1].x * m[0].z * m[3].y - m[3].x * m[0].y * m[1].z + m[3].x * m[0].z * m[1].y; float inv3 = -m[0].y * m[1].z * m[2].w + m[0].y * m[1].w * m[2].z + m[1].y * m[0].z * m[2].w - m[1].y * m[0].w * m[2].z - m[2].y * m[0].z * m[1].w + m[2].y * m[0].w * m[1].z; float inv7 = m[0].x * m[1].z * m[2].w - m[0].x * m[1].w * m[2].z - m[1].x * m[0].z * m[2].w + m[1].x * m[0].w * m[2].z + m[2].x * m[0].z * m[1].w - m[2].x * m[0].w * m[1].z; float inv11 = -m[0].x * m[1].y * m[2].w + m[0].x * m[1].w * m[2].y + m[1].x * m[0].y * m[2].w - m[1].x * m[0].w * m[2].y - m[2].x * m[0].y * m[1].w + m[2].x * m[0].w * m[1].y; float inv15 = m[0].x * m[1].y * m[2].z - m[0].x * m[1].z * m[2].y - m[1].x * m[0].y * m[2].z + m[1].x * m[0].z * m[2].y + m[2].x * m[0].y * m[1].z - m[2].x * m[0].z * m[1].y;
524 float det = m[0].x * inv0 + m[0].y * inv4 + m[0].z * inv8 + m[0].w * inv12; det = 1.0 / det; return det*mat4( inv0, inv1, inv2, inv3,inv4, inv5, inv6, inv7,inv8, inv9, inv10, inv11,inv12, inv13, inv14, inv15);}\n"+ 525 "float sinh(float x) { return (exp(x)-exp(-x))/2.; }\n"+ 526 "float cosh(float x) { return (exp(x)+exp(-x))/2.; }\n"+ 527 "float tanh(float x) { return sinh(x)/cosh(x); }\n"+ 528 "float coth(float x) { return cosh(x)/sinh(x); }\n"+ 529 "float sech(float x) { return 1./cosh(x); }\n"+ 530 "float csch(float x) { return 1./sinh(x); }\n"+ 531 "float asinh(float x) { return log(x+sqrt(x*x+1.)); }\n"+ 532 "float acosh(float x) { return log(x+sqrt(x*x-1.)); }\n"+ 533 "float atanh(float x) { return .5*log((1.+x)/(1.-x)); }\n"+ 534 "float acoth(float x) { return .5*log((x+1.)/(x-1.)); }\n"+ 535 "float asech(float x) { return log((1.+sqrt(1.-x*x))/x); }\n"+ 536 "float acsch(float x) { return log((1.+sqrt(1.+x*x))/x); }\n"; 537 mShaderHeaderLines[0] += 26; 538 } 539 540 //------------------------------------------------------- 541 542 mShaderHeader[1] = ""; 543 mShaderHeaderLines[1] = 0; 544 if( mIs20 ) 545 { 546 mShaderHeader[1] += "#version 300 es\n"+ 547 "#ifdef GL_ES\n"+ 548 "precision highp float;\n"+ 549 "precision highp int;\n"+ 550 "precision mediump sampler3D;\n"+ 551 "#endif\n"; 552 mShaderHeaderLines[1] += 6; 553 } 554 else 555 { 556 if( mDerivatives ) { mShaderHeader[1] += "#ifdef GL_OES_standard_derivatives\n#extension GL_OES_standard_derivatives : enable\n#endif\n"; mShaderHeaderLines[1]+=3; } 557 if( mShaderTextureLOD ) { mShaderHeader[1] += "#extension GL_EXT_shader_texture_lod : enable\n"; mShaderHeaderLines[1]++; } 558 mShaderHeader[1] += "#ifdef GL_ES\n"+ 559 "precision highp float;\n"+ 560 "precision highp int;\n"+ 561 "#endif\n"+ 562 "vec4 texture( sampler2D s, vec2 c) { return texture2D(s,c); }\n"+ 563 "vec4 texture( sampler2D s, vec2 c, float b) { return texture2D(s,c,b); }\n"+ 564 "vec4 texture( samplerCube s, vec3 c ) { return textureCube(s,c); }\n"+ 565 "vec4 texture( samplerCube s, vec3 c, float b) { return textureCube(s,c,b); }\n"+ 566 "float round( float x ) { return floor(x+0.5); }\n"+ 567 "vec2 round(vec2 x) { return floor(x + 0.5); }\n"+ 568 "vec3 round(vec3 x) { return floor(x + 0.5); }\n"+ 569 "vec4 round(vec4 x) { return floor(x + 0.5); }\n"+ 570 "float trunc( float x, float n ) { return floor(x*n)/n; }\n"+ 571 "mat3 transpose(mat3 m) { return mat3(m[0].x, m[1].x, m[2].x, m[0].y, m[1].y, m[2].y, m[0].z, m[1].z, m[2].z); }\n"+ 572 "float determinant( in mat2 m ) { return m[0][0]*m[1][1] - m[0][1]*m[1][0]; }\n"+ 573 "float determinant( mat4 m ) { float b00 = m[0][0] * m[1][1] - m[0][1] * m[1][0], b01 = m[0][0] * m[1][2] - m[0][2] * m[1][0], b02 = m[0][0] * m[1][3] - m[0][3] * m[1][0], b03 = m[0][1] * m[1][2] - m[0][2] * m[1][1], b04 = m[0][1] * m[1][3] - m[0][3] * m[1][1], b05 = m[0][2] * m[1][3] - m[0][3] * m[1][2], b06 = m[2][0] * m[3][1] - m[2][1] * m[3][0], b07 = m[2][0] * m[3][2] - m[2][2] * m[3][0], b08 = m[2][0] * m[3][3] - m[2][3] * m[3][0], b09 = m[2][1] * m[3][2] - m[2][2] * m[3][1], b10 = m[2][1] * m[3][3] - m[2][3] * m[3][1], b11 = m[2][2] * m[3][3] - m[2][3] * m[3][2]; return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;}\n"+ 574 "mat2 inverse(mat2 m) { float det = determinant(m); return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) / det; }\n"+ 575 "mat4 inverse(mat4 m ) { float inv0 = m[1].y*m[2].z*m[3].w - m[1].y*m[2].w*m[3].z - m[2].y*m[1].z*m[3].w + m[2].y*m[1].w*m[3].z + m[3].y*m[1].z*m[2].w - m[3].y*m[1].w*m[2].z; float inv4 = -m[1].x*m[2].z*m[3].w + m[1].x*m[2].w*m[3].z + m[2].x*m[1].z*m[3].w - m[2].x*m[1].w*m[3].z - m[3].x*m[1].z*m[2].w + m[3].x*m[1].w*m[2].z; float inv8 = m[1].x*m[2].y*m[3].w - m[1].x*m[2].w*m[3].y - m[2].x * m[1].y * m[3].w + m[2].x * m[1].w * m[3].y + m[3].x * m[1].y * m[2].w - m[3].x * m[1].w * m[2].y; float inv12 = -m[1].x * m[2].y * m[3].z + m[1].x * m[2].z * m[3].y +m[2].x * m[1].y * m[3].z - m[2].x * m[1].z * m[3].y - m[3].x * m[1].y * m[2].z + m[3].x * m[1].z * m[2].y;
575 float inv1 = -m[0].y*m[2].z * m[3].w + m[0].y*m[2].w * m[3].z + m[2].y * m[0].z * m[3].w - m[2].y * m[0].w * m[3].z - m[3].y * m[0].z * m[2].w + m[3].y * m[0].w * m[2].z; float inv5 = m[0].x * m[2].z * m[3].w - m[0].x * m[2].w * m[3].z - m[2].x * m[0].z * m[3].w + m[2].x * m[0].w * m[3].z + m[3].x * m[0].z * m[2].w - m[3].x * m[0].w * m[2].z; float inv9 = -m[0].x * m[2].y * m[3].w + m[0].x * m[2].w * m[3].y + m[2].x * m[0].y * m[3].w - m[2].x * m[0].w * m[3].y - m[3].x * m[0].y * m[2].w + m[3].x * m[0].w * m[2].y; float inv13 = m[0].x * m[2].y * m[3].z - m[0].x * m[2].z * m[3].y - m[2].x * m[0].y * m[3].z + m[2].x * m[0].z * m[3].y + m[3].x * m[0].y * m[2].z - m[3].x * m[0].z * m[2].y; float inv2 = m[0].y * m[1].z * m[3].w - m[0].y * m[1].w * m[3].z - m[1].y * m[0].z * m[3].w + m[1].y * m[0].w * m[3].z + m[3].y * m[0].z * m[1].w - m[3].y * m[0].w * m[1].z; float inv6 = -m[0].x * m[1].z * m[3].w + m[0].x * m[1].w * m[3].z + m[1].x * m[0].z * m[3].w - m[1].x * m[0].w * m[3].z - m[3].x * m[0].z * m[1].w + m[3].x * m[0].w * m[1].z; float inv10 = m[0].x * m[1].y * m[3].w - m[0].x * m[1].w * m[3].y - m[1].x * m[0].y * m[3].w + m[1].x * m[0].w * m[3].y + m[3].x * m[0].y * m[1].w - m[3].x * m[0].w * m[1].y; float inv14 = -m[0].x * m[1].y * m[3].z + m[0].x * m[1].z * m[3].y + m[1].x * m[0].y * m[3].z - m[1].x * m[0].z * m[3].y - m[3].x * m[0].y * m[1].z + m[3].x * m[0].z * m[1].y; float inv3 = -m[0].y * m[1].z * m[2].w + m[0].y * m[1].w * m[2].z + m[1].y * m[0].z * m[2].w - m[1].y * m[0].w * m[2].z - m[2].y * m[0].z * m[1].w + m[2].y * m[0].w * m[1].z; float inv7 = m[0].x * m[1].z * m[2].w - m[0].x * m[1].w * m[2].z - m[1].x * m[0].z * m[2].w + m[1].x * m[0].w * m[2].z + m[2].x * m[0].z * m[1].w - m[2].x * m[0].w * m[1].z; float inv11 = -m[0].x * m[1].y * m[2].w + m[0].x * m[1].w * m[2].y + m[1].x * m[0].y * m[2].w - m[1].x * m[0].w * m[2].y - m[2].x * m[0].y * m[1].w + m[2].x * m[0].w * m[1].y; float inv15 = m[0].x * m[1].y * m[2].z - m[0].x * m[1].z * m[2].y - m[1].x * m[0].y * m[2].z + m[1].x * m[0].z * m[2].y + m[2].x * m[0].y * m[1].z - m[2].x * m[0].z * m[1].y; float det = m[0].x * inv0 + m[0].y * inv4 + m[0].z * inv8 + m[0].w * inv12; det = 1.0 / det; return det*mat4( inv0, inv1, inv2, inv3,inv4, inv5, inv6, inv7,inv8, inv9, inv10, inv11,inv12, inv13, inv14, inv15);}\n"+ 576 "float sinh(float x) { return (exp(x)-exp(-x))/2.; }\n"+ 577 "float cosh(float x) { return (exp(x)+exp(-x))/2.; }\n"+ 578 "float tanh(float x) { return sinh(x)/cosh(x); }\n"+ 579 "float coth(float x) { return cosh(x)/sinh(x); }\n"+ 580 "float sech(float x) { return 1./cosh(x); }\n"+ 581 "float csch(float x) { return 1./sinh(x); }\n"+ 582 "float asinh(float x) { return log(x+sqrt(x*x+1.)); }\n"+ 583 "float acosh(float x) { return log(x+sqrt(x*x-1.)); }\n"+ 584 "float atanh(float x) { return .5*log((1.+x)/(1.-x)); }\n"+ 585 "float acoth(float x) { return .5*log((x+1.)/(x-1.)); }\n"+ 586 "float asech(float x) { return log((1.+sqrt(1.-x*x))/x); }\n"+ 587 "float acsch(float x) { return log((1.+sqrt(1.+x*x))/x); }\n"; 588 mShaderHeaderLines[1] += 30; 589 if( mShaderTextureLOD ) 590 { 591 mShaderHeader[1] += "vec4 textureLod( sampler2D s, vec2 c, float b) { return texture2DLodEXT(s,c,b); }\n"; 592 mShaderHeader[1] += "vec4 textureGrad( sampler2D s, vec2 c, vec2 dx, vec2 dy) { return texture2DGradEXT(s,c,dx,dy); }\n"; 593 mShaderHeaderLines[1] += 2; 594 595 //mShaderHeader[1] += "vec4 texelFetch( sampler2D s, ivec2 c, int l) { return texture2DLodEXT(s,(vec2(c)+0.5)/vec2(800,450),float(l)); }\n"; 596 //mShaderHeaderLines[1] += 1; 597 } 598 } 599 600 return true; 601 }; 602 603 me.GetCaps = function () 604 { 605 return { mIsGL20 : mIs20, 606 mFloat32Textures: mFloat32Textures != null, 607 mFloat16Textures: mFloat16Textures != null, 608 mDrawBuffers: mDrawBuffers != null, 609 mDepthTextures: mDepthTextures != null, 610 mDerivatives: mDerivatives != null, 611 mShaderTextureLOD: mShaderTextureLOD != null }; 612 }; 613 614 me.GetShaderHeaderLines = function (shaderType) 615 { 616 return mShaderHeaderLines[shaderType]; 617 }; 618 619 me.CheckErrors = function() 620 { 621 var error = mGL.getError(); 622 if( error != mGL.NO_ERROR ) 623 { 624 for( var prop in mGL ) 625 { 626 if( typeof mGL[prop] == 'number' ) 627 { 628 if( mGL[prop] == error ) 629 { 630 console.log( "GL Error " + error + ": " + prop ); 631 break; 632 } 633 } 634 } 635 } 636 }; 637 638 me.Clear = function( flags, ccolor, cdepth, cstencil ) 639 { 640 var mode = 0; 641 if( flags & 1 ) { mode |= mGL.COLOR_BUFFER_BIT; mGL.clearColor( ccolor[0], ccolor[1], ccolor[2], ccolor[3] ); } 642 if( flags & 2 ) { mode |= mGL.DEPTH_BUFFER_BIT; mGL.clearDepth( cdepth ); } 643 if( flags & 4 ) { mode |= mGL.STENCIL_BUFFER_BIT; mGL.clearStencil( cstencil ); } 644 mGL.clear( mode ); 645 }; 646 647 648 me.CreateTexture = function ( type, xres, yres, format, filter, wrap, buffer) 649 { 650 if( mGL===null ) return null; 651 652 var id = mGL.createTexture(); 653 654 var glFoTy = iFormatPI2GL( format ); 655 var glWrap = mGL.REPEAT; if (wrap === me.TEXWRP.CLAMP) glWrap = mGL.CLAMP_TO_EDGE; 656 657 if( type===me.TEXTYPE.T2D ) 658 { 659 mGL.bindTexture( mGL.TEXTURE_2D, id ); 660 661 mGL.texImage2D( mGL.TEXTURE_2D, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 662 mGL.texParameteri( mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_S, glWrap ); 663 mGL.texParameteri( mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_T, glWrap ); 664 665 if (filter === me.FILTER.NONE) 666 { 667 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 668 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 669 } 670 else if (filter === me.FILTER.LINEAR) 671 { 672 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 673 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 674 } 675 else if (filter === me.FILTER.MIPMAP) 676 { 677 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 678 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 679 mGL.generateMipmap(mGL.TEXTURE_2D); 680 } 681 else 682 { 683 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 684 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 685 mGL.generateMipmap(mGL.TEXTURE_2D); 686 } 687 688 mGL.bindTexture( mGL.TEXTURE_2D, null ); 689 } 690 else if( type===me.TEXTYPE.T3D ) 691 { 692 if( mIs20 ) 693 { 694 mGL.bindTexture( mGL.TEXTURE_3D, id ); 695 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_BASE_LEVEL, 0); 696 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAX_LEVEL, Math.log2(xres)); 697 if (filter === me.FILTER.NONE) 698 { 699 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 700 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 701 } 702 else if (filter === me.FILTER.LINEAR) 703 { 704 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 705 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 706 } 707 else if (filter === me.FILTER.MIPMAP) 708 { 709 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 710 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 711 } 712 else 713 { 714 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 715 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 716 mGL.generateMipmap(mGL.TEXTURE_3D); 717 } 718 mGL.texImage3D( mGL.TEXTURE_3D, 0, glFoTy.mGLFormat, xres, yres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 719 720 mGL.texParameteri( mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_R, glWrap ); 721 mGL.texParameteri( mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_S, glWrap ); 722 mGL.texParameteri( mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_T, glWrap ); 723 724 if (filter === me.FILTER.MIPMAP) 725 mGL.generateMipmap( mGL.TEXTURE_3D ); 726 mGL.bindTexture( mGL.TEXTURE_3D, null ); 727 } 728 else 729 { 730 return null; 731 } 732 } 733 else 734 { 735 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, id ); 736 737 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 738 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 739 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 740 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 741 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 742 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glFoTy.mGLFormat, xres, yres, 0, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 743 744 if( filter === me.FILTER.NONE) 745 { 746 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 747 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 748 } 749 else if (filter === me.FILTER.LINEAR) 750 { 751 mGL.texParameteri( mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR ); 752 mGL.texParameteri( mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR ); 753 } 754 else if (filter === me.FILTER.MIPMAP) 755 { 756 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 757 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 758 } 759 760 if (filter === me.FILTER.MIPMAP) 761 mGL.generateMipmap( mGL.TEXTURE_CUBE_MAP ); 762 763 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, null ); 764 } 765 return { mObjectID: id, mXres: xres, mYres: yres, mFormat: format, mType: type, mFilter: filter, mWrap: wrap, mVFlip:false }; 766 }; 767 768 me.CreateTextureFromImage = function ( type, image, format, filter, wrap, flipY) 769 { 770 if( mGL===null ) return null; 771 772 var id = mGL.createTexture(); 773 774 var glFoTy = iFormatPI2GL( format ); 775 776 var glWrap = mGL.REPEAT; if (wrap === me.TEXWRP.CLAMP) glWrap = mGL.CLAMP_TO_EDGE; 777 778 if( type===me.TEXTYPE.T2D ) 779 { 780 mGL.bindTexture(mGL.TEXTURE_2D, id); 781 782 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, flipY); 783 mGL.pixelStorei(mGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); 784 if( mIs20 ) mGL.pixelStorei(mGL.UNPACK_COLORSPACE_CONVERSION_WEBGL, mGL.NONE ); 785 786
786 mGL.texImage2D(mGL.TEXTURE_2D, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image); 787 788 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_S, glWrap); 789 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_T, glWrap); 790 791 if (filter === me.FILTER.NONE) 792 { 793 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 794 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 795 } 796 else if (filter === me.FILTER.LINEAR) 797 { 798 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 799 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 800 } 801 else if( filter === me.FILTER.MIPMAP) 802 { 803 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 804 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 805 mGL.generateMipmap(mGL.TEXTURE_2D); 806 } 807 else 808 { 809 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 810 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 811 mGL.generateMipmap(mGL.TEXTURE_2D); 812 } 813 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 814 mGL.bindTexture(mGL.TEXTURE_2D, null); 815 } 816 else if( type===me.TEXTYPE.T3D ) 817 { 818 return null; 819 } 820 else 821 { 822 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, id ); 823 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, flipY); 824 mGL.activeTexture( mGL.TEXTURE0 ); 825 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[0] ); 826 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[1] ); 827 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, (flipY ? image[3] : image[2]) ); 828 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, (flipY ? image[2] : image[3]) ); 829 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[4] ); 830 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[5] ); 831 832 if( filter === me.FILTER.NONE) 833 { 834 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 835 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 836 } 837 else if (filter === me.FILTER.LINEAR) 838 { 839 mGL.texParameteri( mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR ); 840 mGL.texParameteri( mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR ); 841 } 842 else if (filter === me.FILTER.MIPMAP) 843 { 844 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 845 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 846 mGL.generateMipmap( mGL.TEXTURE_CUBE_MAP ); 847 } 848 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 849 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, null ); 850 } 851 return { mObjectID: id, mXres: image.width, mYres: image.height, mFormat: format, mType: type, mFilter: filter, mWrap:wrap, mVFlip:flipY }; 852 }; 853
854 me.SetSamplerFilter = function (te, filter, doGenerateMipsIfNeeded) 855 { 856 if (te.mFilter === filter) return; 857 858 if (te.mType === me.TEXTYPE.T2D) 859 { 860 mGL.bindTexture(mGL.TEXTURE_2D, te.mObjectID); 861 862 if (filter === me.FILTER.NONE) 863 { 864 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 865 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 866 } 867 else if (filter === me.FILTER.LINEAR) 868 { 869 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 870 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 871 } 872 else if (filter === me.FILTER.MIPMAP) 873 { 874 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 875 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 876 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_2D); 877 } 878 else 879 { 880 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 881 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 882 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_2D); 883 } 884 885 mGL.bindTexture(mGL.TEXTURE_2D, null); 886 887 } 888 else if (te.mType === me.TEXTYPE.T3D) 889 { 890 mGL.bindTexture(mGL.TEXTURE_3D, te.mObjectID); 891 892 if (filter === me.FILTER.NONE) 893 { 894 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 895 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 896 } 897 else if (filter === me.FILTER.LINEAR) 898 { 899 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 900 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 901 } 902 else if (filter === me.FILTER.MIPMAP) 903 { 904 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 905 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 906 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_3D); 907 } 908 else 909 { 910 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 911 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 912 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_3D); 913 } 914 915 mGL.bindTexture(mGL.TEXTURE_3D, null); 916 917 } 918 else 919 { 920 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, te.mObjectID); 921 922 if (filter === me.FILTER.NONE) 923 { 924 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 925 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST); 926 } 927 else if (filter === me.FILTER.LINEAR) 928 { 929 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 930 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR); 931 } 932 else if (filter === me.FILTER.MIPMAP) 933 { 934 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.LINEAR); 935 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.LINEAR_MIPMAP_LINEAR); 936 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_CUBE_MAP); 937 } 938 else 939 { 940 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MAG_FILTER, mGL.NEAREST); 941 mGL.texParameteri(mGL.TEXTURE_CUBE_MAP, mGL.TEXTURE_MIN_FILTER, mGL.NEAREST_MIPMAP_LINEAR); 942 if( doGenerateMipsIfNeeded ) mGL.generateMipmap(mGL.TEXTURE_CUBE_MAP); 943 } 944 945 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 946 } 947 948
949 te.mFilter = filter; 950 }; 951 952 me.SetSamplerWrap = function (te, wrap) 953 { 954 if (te.mWrap === wrap) return; 955 956 var glWrap = mGL.REPEAT; if (wrap === me.TEXWRP.CLAMP) glWrap = mGL.CLAMP_TO_EDGE; 957 958 var id = te.mObjectID; 959 960 if (te.mType === me.TEXTYPE.T2D) 961 { 962 mGL.bindTexture(mGL.TEXTURE_2D, id); 963 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_S, glWrap); 964 mGL.texParameteri(mGL.TEXTURE_2D, mGL.TEXTURE_WRAP_T, glWrap); 965 mGL.bindTexture(mGL.TEXTURE_2D, null); 966 967 } 968 else if (te.mType === me.TEXTYPE.T3D) 969 { 970 mGL.bindTexture(mGL.TEXTURE_3D, id); 971 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_R, glWrap); 972 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_S, glWrap); 973 mGL.texParameteri(mGL.TEXTURE_3D, mGL.TEXTURE_WRAP_T, glWrap); 974 mGL.bindTexture(mGL.TEXTURE_3D, null); 975 } 976 977 te.mWrap = wrap; 978 }; 979 980 me.SetSamplerVFlip = function (te, vflip, image) 981 { 982 if (te.mVFlip === vflip) return; 983 984 var id = te.mObjectID; 985 986 if (te.mType === me.TEXTYPE.T2D) 987 { 988 if( image != null) 989 { 990 mGL.activeTexture( mGL.TEXTURE0 ); 991 mGL.bindTexture(mGL.TEXTURE_2D, id); 992 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, vflip); 993 var glFoTy = iFormatPI2GL( te.mFormat ); 994 mGL.texImage2D(mGL.TEXTURE_2D, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image); 995 mGL.bindTexture(mGL.TEXTURE_2D, null); 996 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 997 } 998 } 999 else if (te.mType === me.TEXTYPE.CUBEMAP) 1000 { 1001 if( image != null) 1002 { 1003 var glFoTy = iFormatPI2GL( te.mFormat ); 1004 mGL.activeTexture( mGL.TEXTURE0 ); 1005 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, id ); 1006 mGL.pixelStorei( mGL.UNPACK_FLIP_Y_WEBGL, vflip); 1007 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[0] ); 1008 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[1] ); 1009 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, (vflip ? image[3] : image[2]) ); 1010 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, (vflip ? image[2] : image[3]) ); 1011 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[4] ); 1012 mGL.texImage2D( mGL.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image[5] ); 1013 mGL.bindTexture( mGL.TEXTURE_CUBE_MAP, null ); 1014 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 1015 } 1016 1017 } 1018 1019 te.mVFlip = vflip; 1020 }; 1021 1022 me.CreateMipmaps = function (te) 1023 { 1024 if( te.mType===me.TEXTYPE.T2D ) 1025 { 1026 mGL.activeTexture(mGL.TEXTURE0); 1027 mGL.bindTexture(mGL.TEXTURE_2D, te.mObjectID); 1028 mGL.generateMipmap(mGL.TEXTURE_2D); 1029 mGL.bindTexture(mGL.TEXTURE_2D, null); 1030 } 1031 else if( te.mType===me.TEXTYPE.CUBEMAP ) 1032 { 1033 mGL.activeTexture(mGL.TEXTURE0); 1034 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, te.mObjectID); 1035 mGL.generateMipmap( mGL.TEXTURE_CUBE_MAP ); 1036 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 1037 } 1038 }; 1039 1040 me.UpdateTexture = function( tex, x0, y0, xres, yres, buffer ) 1041 { 1042 var glFoTy = iFormatPI2GL( tex.mFormat ); 1043 if( tex.mType===me.TEXTYPE.T2D ) 1044 { 1045 mGL.activeTexture( mGL.TEXTURE0); 1046 mGL.bindTexture( mGL.TEXTURE_2D, tex.mObjectID ); 1047 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, tex.mVFlip ); 1048 mGL.texSubImage2D( mGL.TEXTURE_2D, 0, x0, y0, xres, yres, glFoTy.mGLExternal, glFoTy.mGLType, buffer ); 1049 mGL.bindTexture( mGL.TEXTURE_2D, null ); 1050 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 1051 } 1052 }; 1053 1054 me.UpdateTextureFromImage = function( tex, image ) 1055 { 1056 var glFoTy = iFormatPI2GL( tex.mFormat ); 1057 if( tex.mType===me.TEXTYPE.T2D ) 1058 { 1059 mGL.activeTexture( mGL.TEXTURE0 ); 1060 mGL.bindTexture( mGL.TEXTURE_2D, tex.mObjectID ); 1061 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, tex.mVFlip ); 1062 mGL.texImage2D( mGL.TEXTURE_2D, 0, glFoTy.mGLFormat, glFoTy.mGLExternal, glFoTy.mGLType, image ); 1063 mGL.bindTexture( mGL.TEXTURE_2D, null ); 1064 mGL.pixelStorei(mGL.UNPACK_FLIP_Y_WEBGL, false); 1065 } 1066 }; 1067 1068 me.DestroyTexture = function( te ) 1069 { 1070 mGL.deleteTexture( te.mObjectID ); 1071 }; 1072 1073 me.AttachTextures = function (num, t0, t1, t2, t3) 1074 { 1075 if (num > 0 && t0 != null) 1076 { 1077 mGL.activeTexture(mGL.TEXTURE0); 1078 if (t0.mType === me.TEXTYPE.T2D) mGL.bindTexture(mGL.TEXTURE_2D, t0.mObjectID);
1079 else if (t0.mType === me.TEXTYPE.T3D) mGL.bindTexture(mGL.TEXTURE_3D, t0.mObjectID); 1080 else if (t0.mType === me.TEXTYPE.CUBEMAP) mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, t0.mObjectID); 1081 } 1082 1083 if (num > 1 && t1 != null) 1084 { 1085 mGL.activeTexture(mGL.TEXTURE1); 1086 if (t1.mType === me.TEXTYPE.T2D) mGL.bindTexture(mGL.TEXTURE_2D, t1.mObjectID); 1087 else if (t1.mType === me.TEXTYPE.T3D) mGL.bindTexture(mGL.TEXTURE_3D, t1.mObjectID); 1088 else if (t1.mType === me.TEXTYPE.CUBEMAP) mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, t1.mObjectID); 1089 } 1090 1091 if (num > 2 && t2 != null) 1092 { 1093 mGL.activeTexture(mGL.TEXTURE2); 1094 if (t2.mType === me.TEXTYPE.T2D) mGL.bindTexture(mGL.TEXTURE_2D, t2.mObjectID); 1095 else if (t2.mType === me.TEXTYPE.T3D) mGL.bindTexture(mGL.TEXTURE_3D, t2.mObjectID); 1096 else if (t2.mType === me.TEXTYPE.CUBEMAP) mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, t2.mObjectID); 1097 } 1098 1099 if (num > 3 && t3 != null) 1100 { 1101 mGL.activeTexture(mGL.TEXTURE3); 1102 if (t3.mType === me.TEXTYPE.T2D) mGL.bindTexture(mGL.TEXTURE_2D, t3.mObjectID); 1103 else if (t3.mType === me.TEXTYPE.T3D) mGL.bindTexture(mGL.TEXTURE_3D, t3.mObjectID); 1104 else if (t3.mType === me.TEXTYPE.CUBEMAP) mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, t3.mObjectID); 1105 } 1106 }; 1107 1108 me.DettachTextures = function() 1109 { 1110 mGL.activeTexture(mGL.TEXTURE0); 1111 mGL.bindTexture(mGL.TEXTURE_2D, null); 1112 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 1113 1114 mGL.activeTexture(mGL.TEXTURE1); 1115 mGL.bindTexture(mGL.TEXTURE_2D, null); 1116 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 1117 1118 mGL.activeTexture(mGL.TEXTURE2); 1119 mGL.bindTexture(mGL.TEXTURE_2D, null); 1120 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 1121 1122 mGL.activeTexture(mGL.TEXTURE3); 1123 mGL.bindTexture(mGL.TEXTURE_2D, null); 1124 mGL.bindTexture(mGL.TEXTURE_CUBE_MAP, null); 1125 }; 1126 1127 me.CreateRenderTarget = function ( color0, color1, color2, color3, depth, wantZbuffer ) 1128 { 1129 var id = mGL.createFramebuffer(); 1130 mGL.bindFramebuffer(mGL.FRAMEBUFFER, id); 1131 1132 if (depth === null) 1133 { 1134 if( wantZbuffer===true ) 1135 { 1136 var zb = mGL.createRenderbuffer(); 1137 mGL.bindRenderbuffer(mGL.RENDERBUFFER, zb); 1138 mGL.renderbufferStorage(mGL.RENDERBUFFER, mGL.DEPTH_COMPONENT16, color0.mXres, color0.mYres); 1139 1140 mGL.framebufferRenderbuffer(mGL.FRAMEBUFFER, mGL.DEPTH_ATTACHMENT, mGL.RENDERBUFFER, zb); 1141 } 1142 } 1143 else 1144 { 1145 mGL.framebufferTexture2D(mGL.FRAMEBUFFER, mGL.DEPTH_ATTACHMENT, mGL.TEXTURE_2D, depth.mOb
1145jectID, 0); 1146 } 1147 1148 if( color0 !=null ) mGL.framebufferTexture2D(mGL.FRAMEBUFFER, mGL.COLOR_ATTACHMENT0, mGL.TEXTURE_2D, color0.mObjectID, 0); 1149 1150 if (mGL.checkFramebufferStatus(mGL.FRAMEBUFFER) != mGL.FRAMEBUFFER_COMPLETE) 1151 return null; 1152 1153 mGL.bindRenderbuffer(mGL.RENDERBUFFER, null); 1154 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1155 return { mObjectID: id, mTex0: color0 }; 1156 }; 1157 1158 me.DestroyRenderTarget = function ( tex ) 1159 { 1160 mGL.deleteFramebuffer(tex.mObjectID); 1161 }; 1162 1163 me.SetRenderTarget = function (tex) 1164 { 1165 if( tex===null ) 1166 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1167 else 1168 mGL.bindFramebuffer(mGL.FRAMEBUFFER, tex.mObjectID); 1169 1170 //mGL.drawBuffers([mGL.COLOR_ATTACHMENT0, mGL.COLOR_ATTACHMENT1]); 1171 }; 1172 1173 me.CreateRenderTargetNew = function ( wantColor0, wantZbuffer, xres, yres, samples ) 1174 { 1175 var id = mGL.createFramebuffer(); 1176 mGL.bindFramebuffer(mGL.FRAMEBUFFER, id); 1177 1178 if( wantZbuffer===true ) 1179 { 1180 var zb = mGL.createRenderbuffer(); 1181 mGL.bindRenderbuffer(mGL.RENDERBUFFER, zb); 1182 1183 if( samples==1 ) 1184 mGL.renderbufferStorage(mGL.RENDERBUFFER, mGL.DEPTH_COMPONENT16, xres, yres); 1185 else 1186 mGL.renderbufferStorageMultisample(mGL.RENDERBUFFER, samples, mGL.DEPTH_COMPONENT16, xres, yres); 1187 mGL.framebufferRenderbuffer(mGL.FRAMEBUFFER, mGL.DEPTH_ATTACHMENT, mGL.RENDERBUFFER, zb); 1188 } 1189 1190 if( wantColor0 ) 1191 { 1192 var cb = mGL.createRenderbuffer(); 1193 mGL.bindRenderbuffer(mGL.RENDERBUFFER, cb); 1194 if( samples==1 ) 1195 mGL.renderbufferStorage(mGL.RENDERBUFFER, mGL.RGBA8, xres, yres); 1196 else 1197 mGL.renderbufferStorageMultisample(mGL.RENDERBUFFER, samples, mGL.RGBA8, xres, yres); 1198 mGL.framebufferRenderbuffer(mGL.FRAMEBUFFER, mGL.COLOR_ATTACHMENT0, mGL.RENDERBUFFER, cb); 1199 } 1200 1201 if (mGL.checkFramebufferStatus(mGL.FRAMEBUFFER) != mGL.FRAMEBUFFER_COMPLETE) 1202 { 1203 return null; 1204 } 1205 mGL.bindRenderbuffer(mGL.RENDERBUFFER, null); 1206 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1207 return { mObjectID: id, mXres: xres, mYres:yres, mTex0: color0 }; 1208 }; 1209 1210 me.CreateRenderTargetCubeMap = function ( color0, depth, wantZbuffer ) 1211 { 1212 var id = mGL.createFramebuffer(); 1213 mGL.bindFramebuffer(mGL.FRAMEBUFFER, id); 1214 1215 if (depth === null) 1216 { 1217 if( wantZbuffer===true ) 1218 { 1219 var zb = mGL.createRenderbuffer(); 1220 mGL.bindRenderbuffer(mGL.RENDERBUFFER, zb); 1221 mGL.renderbufferStorage(mGL.RENDERBUFFER, mGL.DEPTH_COMPONENT16, color0.mXres, color0.mYres); 1222 mGL.framebufferRenderbuffer(mGL.FRAMEBUFFER, mGL.DEPTH_ATTACHMENT, mGL.RENDERBUFFER, zb); 1223 } 1224 } 1225 else 1226 { 1227 mGL.framebufferTexture2D(mGL.FRAMEBUFFER, mGL.DEPTH_ATTACHMENT, mGL.TEXTURE_2D, depth.mOb
1227jectID, 0); 1228 } 1229 1230 if( color0 !=null ) mGL.framebufferTexture2D(mGL.FRAMEBUFFER, mGL.COLOR_ATTACHMENT0, mGL.TEXTURE_CUBE_MAP_POSITIVE_X, color0.mObjectID, 0); 1231 1232 if (mGL.checkFramebufferStatus(mGL.FRAMEBUFFER) != mGL.FRAMEBUFFER_COMPLETE) 1233 return null; 1234 1235 mGL.bindRenderbuffer(mGL.RENDERBUFFER, null); 1236 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1237 return { mObjectID: id, mTex0: color0 }; 1238 }; 1239 1240 me.SetRenderTargetCubeMap = function (fbo, face) 1241 { 1242 if( fbo===null ) 1243 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1244 else 1245 { 1246 mGL.bindFramebuffer(mGL.FRAMEBUFFER, fbo.mOb
1246jectID); 1247 mGL.framebufferTexture2D(mGL.FRAMEBUFFER, mGL.COLOR_ATTACHMENT0, mGL.TEXTURE_CUBE_MAP_POSITIVE_X+face, fbo.mTex0.mObjectID, 0); 1248 } 1249 }; 1250 1251 1252 me.BlitRenderTarget = function( dst, src ) 1253 { 1254 mGL.bindFramebuffer(mGL.READ_FRAMEBUFFER, src.mObjectID); 1255 mGL.bindFramebuffer(mGL.DRAW_FRAMEBUFFER, dst.mObjectID); 1256 mGL.clearBufferfv(mGL.COLOR, 0, [0.0, 0.0, 0.0, 1.0]); 1257 mGL.blitFramebuffer( 0, 0, src.mXres, src.mYres, 1258 0, 0, src.mXres, src.mYres, 1259 mGL.COLOR_BUFFER_BIT, mGL.LINEAR 1260 ); 1261 }; 1262 1263 me.SetViewport = function( vp ) 1264 { 1265 mGL.viewport( vp[0], vp[1], vp[2], vp[3] ); 1266 }; 1267 1268 me.SetWriteMask = function( c0, c1, c2, c3, z ) 1269 { 1270 mGL.depthMask(z); 1271 mGL.colorMask(c0,c0,c0,c0); 1272 }; 1273 1274 me.SetState = function( stateName, stateValue ) 1275 { 1276 if (stateName === me.RENDSTGATE.WIREFRAME) 1277 { 1278 if( stateValue ) mGL.polygonMode( mGL.FRONT_AND_BACK, mGL.LINE ); 1279 else mGL.polygonMode( mGL.FRONT_AND_BACK, mGL.FILL ); 1280 } 1281 else if (stateName === me.RENDSTGATE.FRONT_FACE) 1282 { 1283 if( stateValue ) mGL.cullFace( mGL.BACK ); 1284 else mGL.cullFace( mGL.FRONT ); 1285 } 1286 else if (stateName === me.RENDSTGATE.CULL_FACE) 1287 { 1288 if( stateValue ) mGL.enable( mGL.CULL_FACE ); 1289 else mGL.disable( mGL.CULL_FACE ); 1290 } 1291 else if (stateName === me.RENDSTGATE.DEPTH_TEST) 1292 { 1293 if( stateValue ) mGL.enable( mGL.DEPTH_TEST ); 1294 else mGL.disable( mGL.DEPTH_TEST ); 1295 } 1296 else if (stateName === me.RENDSTGATE.ALPHA_TO_COVERAGE) 1297 { 1298 if( stateValue ) { mGL.enable( mGL.SAMPLE_ALPHA_TO_COVERAGE ); } 1299 else { mGL.disable( mGL.SAMPLE_ALPHA_TO_COVERAGE ); } 1300 } 1301 }; 1302 1303 me.SetMultisample = function( v) 1304 { 1305 if( v===true ) 1306 { 1307 mGL.enable(mGL.SAMPLE_COVERAGE); 1308 mGL.sampleCoverage(1.0, false); 1309 } 1310 else 1311 { 1312 mGL.disable(mGL.SAMPLE_COVERAGE); 1313 } 1314 }; 1315 1316 me.GetTranslatedShaderSource = function (shader) 1317 { 1318 if( mGL===null ) return null; 1319 if( mDebugShader===null ) return null; 1320 let vfs = mGL.getAttachedShaders(shader.mProgram); 1321 let str = mDebugShader.getTranslatedShaderSource(vfs[1]); 1322 let parts = str.split("GLSL END"); str = (parts.length<2) ? str : parts[1]; 1323 return str; 1324 }; 1325 1326 me.CreateShader = function (vsSource, fsSource, preventCache, forceSynch, onResolve) 1327 { 1328 if( mGL===null ) return; 1329 1330 var vs = mGL.createShader( mGL.VERTEX_SHADER ); 1331 var fs = mGL.createShader( mGL.FRAGMENT_SHADER ); 1332 1333 vsSource = mShaderHeader[0] + vsSource; 1334 fsSource = mShaderHeader[1] + fsSource; 1335 1336 if( preventCache ) 1337 { 1338 let vran = Math.random().toString(36).substring(7); 1339 let fran = Math.random().toString(36).substring(7); 1340 vsSource += "\n#define K" + vran + "\n"; 1341 fsSource += "\n#define K" + fran + "\n"; 1342 } 1343 1344 var timeStart = (new Date()).getTime(); 1345 1346 mGL.shaderSource(vs, vsSource); 1347 mGL.shaderSource(fs, fsSource); 1348 mGL.compileShader(vs); 1349 mGL.compileShader(fs); 1350 1351 var pr = mGL.createProgram(); 1352 mGL.attachShader(pr, vs); 1353 mGL.attachShader(pr, fs); 1354 mGL.linkProgram(pr); 1355 1356 //------------- 1357 let checkErrors = function() 1358 { 1359 if (!mGL.getProgramParameter(pr, mGL.LINK_STATUS)) 1360 { 1361 // vs error 1362 if (!mGL.getShaderParameter(vs, mGL.COMPILE_STATUS)) 1363 { 1364 let vsLog = mGL.getShaderInfoLog(vs); 1365 onResolve(false, { mErrorType: 0, mErrorStr: vsLog }); 1366 mGL.deleteProgram(pr); 1367 } 1368 // fs error 1369 else if (!mGL.getShaderParameter(fs, mGL.COMPILE_STATUS)) 1370 { 1371 let fsLog = mGL.getShaderInfoLog(fs); 1372 onResolve(false, { mErrorType: 1, mErrorStr: fsLog }); 1373 mGL.deleteProgram(pr); 1374 } 1375 // link error 1376 else 1377 { 1378 let infoLog = mGL.getProgramInfoLog(pr); 1379 onResolve(false, { mErrorType: 2, mErrorStr: infoLog }); 1380 mGL.deleteProgram(pr); 1381 } 1382 } 1383 // no errors 1384 else 1385 { 1386 let compilationTime = (new Date()).getTime() - timeStart; 1387 onResolve(true, { mProgram: pr, mTime: compilationTime }); 1388 } 1389 }; 1390 1391 // check compilation 1392 if (mAsynchCompile === null || forceSynch===true ) 1393 { 1394 checkErrors(); 1395 } 1396 else 1397 { 1398 let loopCheckCompletion = function () 1399 { 1400 if( mGL.getProgramParameter(pr, mAsynchCompile.COMPLETION_STATUS_KHR
1400) === true ) 1401 checkErrors(); 1402 else 1403 setTimeout(loopCheckCompletion, 10); 1404 }; 1405 setTimeout(loopCheckCompletion, 10); 1406 } 1407 }; 1408 1409 me.AttachShader = function( shader ) 1410 { 1411 if( shader===null ) 1412 { 1413 mBindedShader = null; 1414 mGL.useProgram( null ); 1415 } 1416 else 1417 { 1418 mBindedShader = shader; 1419 mGL.useProgram(shader.mProgram); 1420 } 1421 }; 1422 1423 me.DetachShader = function () 1424 { 1425 mGL.useProgram(null); 1426 }; 1427 1428 me.DestroyShader = function( tex ) 1429 { 1430 mGL.deleteProgram(tex.mProgram); 1431 }; 1432 1433 me.GetAttribLocation = function (shader, name) 1434 { 1435 return mGL.getAttribLocation(shader.mProgram, name); 1436 }; 1437 1438 me.SetShaderConstantLocation = function (shader, name) 1439 { 1440 return mGL.getUniformLocation(shader.mProgram, name); 1441 }; 1442 1443 me.SetShaderConstantMat4F = function( uname, params, istranspose ) 1444 { 1445 var program = mBindedShader; 1446 1447 let pos = mGL.getUniformLocation( program.mProgram, uname ); 1448 if( pos===null ) 1449 return false; 1450 1451 if( istranspose===false ) 1452 { 1453 var tmp = new Float32Array( [ params[0], params[4], params[ 8], params[12], 1454 params[1], params[5], params[ 9], params[13], 1455 params[2], params[6], params[10], params[14], 1456 params[3], params[7], params[11], params[15] ] ); 1457 mGL.uniformMatrix4fv(pos,false,tmp); 1458 } 1459 else 1460 mGL.uniformMatrix4fv(pos,false,new Float32Array(params) ); 1461 return true; 1462 }; 1463 1464 me.SetShaderConstant1F_Pos = function(pos, x) 1465 { 1466 mGL.uniform1f(pos, x); 1467 return true; 1468 }; 1469 1470 me.SetShaderConstant1FV_Pos = function(pos, x) 1471 { 1472 mGL.uniform1fv(pos, x); 1473 return true; 1474 }; 1475 1476 me.SetShaderConstant1F = function( uname, x ) 1477 { 1478 var pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1479 if (pos === null) 1480 return false; 1481 mGL.uniform1f(pos, x); 1482 return true; 1483 }; 1484 1485 me.SetShaderConstant1I = function(uname, x) 1486 { 1487 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1488 if (pos === null) 1489 return false; 1490 mGL.uniform1i(pos, x); 1491 return true; 1492 }; 1493 me.SetShaderConstant1I_Pos = function(pos, x) 1494 { 1495 mGL.uniform1i(pos, x); 1496 return true; 1497 }; 1498 1499 1500 me.SetShaderConstant2F = function(uname, x) 1501 { 1502 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1503 if (pos === null) 1504 return false; 1505 mGL.uniform2fv(pos, x); 1506 return true; 1507 }; 1508 1509 me.SetShaderConstant3F = function(uname, x, y, z) 1510 { 1511 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1512 if (pos === null) 1513 return false; 1514 mGL.uniform3f(pos, x, y, z); 1515 return true; 1516 }; 1517 1518 me.SetShaderConstant1FV = function(uname, x) 1519 { 1520 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1521 if (pos === null) 1522 return false; 1523 mGL.uniform1fv(pos, new Float32Array(x)
1523); 1524 return true; 1525 }; 1526 1527 me.SetShaderConstant3FV = function(uname, x) 1528 { 1529 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1530 if (pos === null) return false; 1531 mGL.uniform3fv(pos, new Float32Array(x) ); 1532 return true; 1533 }; 1534 1535 me.SetShaderConstant4FV = function(uname, x) 1536 { 1537 let pos = mGL.getUniformLocation(mBindedShader.mProgram, uname); 1538 if (pos === null) return false; 1539 mGL.uniform4fv(pos, new Float32Array(x) ); 1540 return true; 1541 }; 1542 1543 me.SetShaderTextureUnit = function( uname, unit ) 1544 { 1545 var program = mBindedShader; 1546 let pos = mGL.getUniformLocation(program.mProgram, uname); 1547 if (pos === null) return false; 1548 mGL.uniform1i(pos, unit); 1549 return true; 1550 }; 1551 1552 me.CreateVertexArray = function( data, mode ) 1553 { 1554 let id = mGL.createBuffer(); 1555 mGL.bindBuffer(mGL.ARRAY_BUFFER, id); 1556 if (mode === me.BUFTYPE.STATIC) 1557 mGL.bufferData(mGL.ARRAY_BUFFER, data, mGL.STATIC_DRAW); 1558 else 1559 mGL.bufferData(mGL.ARRAY_BUFFER, data, mGL.DYNAMIC_DRAW); 1560 return { mObject: id }; 1561 }; 1562 1563 me.CreateIndexArray = function( data, mode ) 1564 { 1565 let id = mGL.createBuffer(); 1566 mGL.bindBuffer(mGL.ELEMENT_ARRAY_BUFFER, id ); 1567 if (mode === me.BUFTYPE.STATIC) 1568 mGL.bufferData(mGL.ELEMENT_ARRAY_BUFFER, data, mGL.STATIC_DRAW); 1569 else 1570 mGL.bufferData(mGL.ELEMENT_ARRAY_BUFFER, data, mGL.DYNAMIC_DRAW); 1571 return { mObject: id }; 1572 }; 1573 1574 me.DestroyArray = function( tex ) 1575 { 1576 mGL.destroyBuffer(tex.mObject); 1577 }; 1578 1579 me.AttachVertexArray = function( tex, attribs, pos ) 1580 { 1581 let shader = mBindedShader; 1582 1583 mGL.bindBuffer( mGL.ARRAY_BUFFER, tex.mObject); 1584 1585 var num = attribs.mChannels.length; 1586 var stride = attribs.mStride; 1587 1588 var offset = 0; 1589 for (var i = 0; i < num; i++) 1590 { 1591 var id = pos[i]; 1592 mGL.enableVertexAttribArray(id); 1593 var dtype = mGL.FLOAT; 1594 var dsize = 4; 1595 if( attribs.mChannels[i].mType === me.TYPE.UINT8 ) { dtype = mGL.UNSIGNED_BYTE; dsize = 1; } 1596 else if( attribs.mChannels[i].mType === me.TYPE.UINT16 ) { dtype = mGL.UNSIGNED_SHORT; dsize = 2; } 1597 else if( attribs.mChannels[i].mType === me.TYPE.FLOAT32 ) { dtype = mGL.FLOAT; dsize = 4; } 1598 mGL.vertexAttribPointer(id, attribs.mChannels[i].mNumComponents, dtype, attribs.mChannels[i].mNormalize, stride, offset); 1599 offset += attribs.mChannels[i].mNumComponents * dsize; 1600 } 1601 }; 1602 1603 me.AttachIndexArray = function( tex ) 1604 { 1605 mGL.bindBuffer(mGL.ELEMENT_ARRAY_BUFFER, tex.mObject); 1606 }; 1607 1608 me.DetachVertexArray = function (tex, attribs) 1609 { 1610 let num = attribs.mChannels.length; 1611 for (let i = 0; i < num; i++) 1612 mGL.disableVertexAttribArray(i); 1613 mGL.bindBuffer(mGL.ARRAY_BUFFER, null); 1614 }; 1615 1616 me.DetachIndexArray = function( tex ) 1617 { 1618 mGL.bindBuffer(mGL.ELEMENT_ARRAY_BUFFER, null); 1619 }; 1620 1621 me.DrawPrimitive = function( typeOfPrimitive, num, useIndexArray, numInstances ) 1622 { 1623 let glType = mGL.POINTS; 1624 if( typeOfPrimitive===me.PRIMTYPE.POINTS ) glType = mGL.POINTS; 1625 if( typeOfPrimitive===me.PRIMTYPE.LINES ) glType = mGL.LINES; 1626 if( typeOfPrimitive===me.PRIMTYPE.LINE_LOOP ) glType = mGL.LINE_LOOP; 1627 if( typeOfPrimitive===me.PRIMTYPE.LINE_STRIP ) glType = mGL.LINE_STRIP; 1628 if( typeOfPrimitive===me.PRIMTYPE.TRIANGLES ) glType = mGL.TRIANGLES; 1629 if( typeOfPrimitive===me.PRIMTYPE.TRIANGLE_STRIP ) glType = mGL.TRIANGLE_STRIP; 1630 1631 if( numInstances<=1 ) 1632 { 1633 if( useIndexArray ) mGL.drawElements( glType, num, mGL.UNSIGNED_SHORT, 0 ); 1634 else mGL.drawArrays( glType, 0, num ); 1635 } 1636 else 1637 { 1638 mGL.drawArraysInstanced(glType, 0, num, numInstances); 1639 mGL.drawElementsInstanced( glType, num, mGL.UNSIGNED_SHORT, 0, numInstances); 1640 } 1641 }; 1642 1643 1644 me.DrawFullScreenTriangle_XY = function( vpos ) 1645 { 1646 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_Tri ); 1647 mGL.vertexAttribPointer( vpos, 2, mGL.FLOAT, false, 0, 0 ); 1648 mGL.enableVertexAttribArray( vpos ); 1649 mGL.drawArrays( mGL.TRIANGLES, 0, 3 ); 1650 mGL.disableVertexAttribArray( vpos ); 1651 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 1652 }; 1653 1654 1655 me.DrawUnitQuad_XY = function( vpos ) 1656 { 1657 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_Quad ); 1658 mGL.vertexAttribPointer( vpos, 2, mGL.FLOAT, false, 0, 0 ); 1659 mGL.enableVertexAttribArray( vpos ); 1660 mGL.drawArrays( mGL.TRIANGLES, 0, 6 ); 1661 mGL.disableVertexAttribArray( vpos ); 1662 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 1663 }; 1664 1665 me.DrawUnitCube_XYZ_NOR = function( vpos ) 1666 { 1667 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_CubePosNor ); 1668 mGL.vertexAttribPointer( vpos[0], 3, mGL.FLOAT, false, 0, 0 ); 1669 mGL.vertexAttribPointer( vpos[1], 3, mGL.FLOAT, false, 0, 0 ); 1670 mGL.enableVertexAttribArray( vpos[0] ); 1671 mGL.enableVertexAttribArray( vpos[1] ); 1672 mGL.drawArrays(mGL.TRIANGLE_STRIP, 0, 4); 1673 mGL.drawArrays(mGL.TRIANGLE_STRIP, 4, 4); 1674 mGL.drawArrays(mGL.TRIANGLE_STRIP, 8, 4); 1675 mGL.drawArrays(mGL.TRIANGLE_STRIP, 12, 4); 1676 mGL.drawArrays(mGL.TRIANGLE_STRIP, 16, 4); 1677 mGL.drawArrays(mGL.TRIANGLE_STRIP, 20, 4); 1678 mGL.disableVertexAttribArray( vpos[0] ); 1679 mGL.disableVertexAttribArray( vpos[1] ); 1680 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 1681 } 1682 1683 me.DrawUnitCube_XYZ = function( vpos ) 1684 { 1685 mGL.bindBuffer( mGL.ARRAY_BUFFER, mVBO_CubePos ); 1686 mGL.vertexAttribPointer( vpos, 3, mGL.FLOAT, false, 0, 0 ); 1687 mGL.enableVertexAttribArray( vpos ); 1688 mGL.drawArrays(mGL.TRIANGLE_STRIP, 0, 4); 1689 mGL.drawArrays(mGL.TRIANGLE_STRIP, 4, 4); 1690 mGL.drawArrays(mGL.TRIANGLE_STRIP, 8, 4); 1691 mGL.drawArrays(mGL.TRIANGLE_STRIP, 12, 4); 1692 mGL.drawArrays(mGL.TRIANGLE_STRIP, 16, 4); 1693 mGL.drawArrays(mGL.TRIANGLE_STRIP, 20, 4); 1694 mGL.disableVertexAttribArray( vpos ); 1695 mGL.bindBuffer( mGL.ARRAY_BUFFER, null ); 1696 } 1697 1698 me.SetBlend = function( enabled ) 1699 { 1700 if( enabled ) 1701 { 1702 mGL.enable( mGL.BLEND ); 1703 mGL.blendEquationSeparate( mGL.FUNC_ADD, mGL.FUNC_ADD ); 1704 mGL.blendFuncSeparate( mGL.SRC_ALPHA, mGL.ONE_MINUS_SRC_ALPHA, mGL.ONE, mGL.ONE_MINUS_SRC_ALPHA ); 1705 } 1706 else 1707 { 1708 mGL.disable( mGL.BLEND ); 1709 } 1710 }; 1711 1712 me.GetPixelData = function( data, offset, xres, yres ) 1713 { 1714 mGL.readPixels(0, 0, xres, yres, mGL.RGBA, mGL.UNSIGNED_BYTE, data, offset); 1715 }; 1716 1717 me.GetPixelDataRenderTarget = function( obj, data, xres, yres ) 1718 { 1719 mGL.bindFramebuffer(mGL.FRAMEBUFFER, obj.mObjectID); 1720 mGL.readBuffer(mGL.COLOR_ATTACHMENT0); 1721 mGL.readPixels(0, 0, xres, yres, mGL.RGBA, mGL.FLOAT, data, 0); 1722 mGL.bindFramebuffer(mGL.FRAMEBUFFER, null); 1723 }; 1724 return me; 1725} 1726//============================================================================== 1727// 1728// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 1729// 1730// piShading 1731// 1732//============================================================================== 1733 1734function smoothstep(a, b, x) 1735{ 1736 x = (x - a) / (b - a);
1737 if (x < 0) x = 0; else if (x > 1) x = 1; 1738 return x * x * (3.0 - 2.0 * x); 1739} 1740 1741function clamp01(x) 1742{ 1743 if( x < 0.0 ) x = 0.0; 1744 if( x > 1.0 ) x = 1.0; 1745 return x; 1746} 1747 1748function clamp(x, a, b) 1749{ 1750 if( x < a ) x = a; 1751 if( x > b ) x = b; 1752 return x; 1753} 1754 1755function screen(a, b) 1756{ 1757 return 1.0 - (1.0 - a) * (1.0 - b); 1758} 1759 1760function parabola(x) 1761{ 1762 return 4.0 * x * (1.0 - x); 1763} 1764 1765function min(a, b) 1766{ 1767 return (a < b) ? a : b; 1768} 1769 1770function max(a, b) 1771{ 1772 return (a > b) ? a : b; 1773} 1774 1775function noise( x ) 1776{ 1777 function grad(i, j, x, y) 1778 { 1779 var h = 7 * i + 131 * j; 1780 h = (h << 13) ^ h; 1781 h = (h * (h * h * 15731 + 789221) + 1376312589); 1782 1783 var rx = (h & 0x20000000) ? x : -x; 1784 var ry = (h & 0x10000000) ? y : -y; 1785 1786 return rx + ry; 1787 } 1788 1789 var i = [ Math.floor(x[0]), Math.floor(x[1]) ]; 1790 var f = [ x[0] - i[0], x[1] - i[1] ]; 1791 var w = [ f[0]*f[0]*(3.0-2.0*f[0]), f[1]*f[1]*(3.0-2.0*f[1]) ]; 1792 1793 var a = grad( i[0]+0, i[1]+0, f[0]+0.0, f[1]+0.0 ); 1794 var b = grad( i[0]+1, i[1]+0, f[0]-1.0, f[1]+0.0 ); 1795 var c = grad( i[0]+0, i[1]+1, f[0]+0.0, f[1]-1.0 ); 1796 var d = grad( i[0]+1, i[1]+1, f[0]-1.0, f[1]-1.0 ); 1797 1798 return a + (b-a)*w[0] + (c-a)*w[1] + (a-b-c+d)*w[0]*w[1]; 1799}//============================================================================== 1800// 1801// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 1802// 1803// piVecTypes 1804// 1805//============================================================================== 1806 1807 1808function vec3( a, b, c ) 1809{ 1810 return [ a, b, c ]; 1811} 1812 1813function add( a, b ) 1814{ 1815 return [ a[0]+b[0], a[1]+b[1], a[2]+b[2] ]; 1816} 1817 1818function sub( a, b ) 1819{ 1820 return [ a[0]-b[0], a[1]-b[1], a[2]-b[2] ]; 1821} 1822 1823function mul( a, s ) 1824{ 1825 return [ a[0]*s, a[1]*s, a[2]*s ]; 1826} 1827 1828function cross( a, b ) 1829{ 1830 return [ a[1]*b[2] - a[2]*b[1], 1831 a[2]*b[0] - a[0]*b[2], 1832 a[0]*b[1] - a[1]*b[0] ]; 1833} 1834 1835function dot( a, b ) 1836{ 1837 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; 1838} 1839 1840function normalize( v ) 1841{ 1842 var is = 1.0 / Math.sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); 1843 return [ v[0]*is, v[1]*is, v[2]*is ]; 1844} 1845 1846function createCirclePoint( cen, uuu, vvv, rad, s, t ) 1847{ 1848 return [ cen[0] + rad*(uuu[0]*s + vvv[0]*t), 1849 cen[1] + rad*(uuu[1]*s + vvv[1]*t), 1850 cen[2] + rad*(uuu[2]*s + vvv[2]*t) ]; 1851} 1852 1853function createTangent( a, b, c ) 1854{ 1855 var cb = normalize( [ c[0]-b[0], c[1]-b[1], c[2]-b[2] ] ); 1856 var ba = normalize( [ b[0]-a[0], b[1]-a[1], b[2]-a[2] ] ); 1857 return normalize( [ ba[0]+cb[0], ba[1]+cb[1], ba[2]+cb[2] ] ); 1858 1859} 1860 1861//=================================== 1862 1863function vec4( a, b, c, d ) 1864{ 1865 return [ a, b, c, d ]; 1866} 1867 1868function getXYZ( v ) 1869{ 1870 return [ v[0], v[1], v[2] ]; 1871} 1872 1873//=================================== 1874 1875function setIdentity() 1876{ 1877 return [ 1.0, 0.0, 0.0, 0.0, 1878 0.0, 1.0, 0.0, 0.0, 1879 0.0, 0.0, 1.0, 0.0, 1880 0.0, 0.0, 0.0, 1.0 ]; 1881} 1882 1883function setRotationX( t ) 1884{ 1885 var sint = Math.sin(t); 1886 var cost = Math.cos(t); 1887 1888 return [ 1.0, 0.0, 0.0, 0.0, 1889 0.0, cost, -sint, 0.0, 1890 0.0, sint, cost, 0.0, 1891 0.0, 0.0, 0.0, 1.0 ]; 1892} 1893 1894function setRotationY( t ) 1895{ 1896 var sint = Math.sin(t); 1897 var cost = Math.cos(t); 1898 1899 return [ cost, 0.0, -sint, 0.0, 1900 0.0, 1.0, 0.0, 0.0, 1901 sint, 0.0, cost, 0.0, 1902 0.0, 0.0, 0.0, 1.0 ]; 1903} 1904 1905function extractRotationEuler( m) 1906{ 1907 var res = []; 1908 if (m[0] == 1.0) 1909 { 1910 res[0] = Math.atan2(m[2], m[11]); 1911 res[1] = 0.0; 1912 res[2] = 0.0; 1913 1914 } 1915 else if (m[0] == -1.0) 1916 { 1917 res[0] = Math.atan2( m[2], m[11]); 1918 res[1] = 0.0; 1919 res[2] = 0.0; 1920 } 1921 else 1922 { 1923 res[0] = Math.atan2( -m[9], m[10]); 1924 res[1] = Math.atan2( m[8], Math.sqrt(m[9]*m[9] + m[10]*m[10])); 1925 res[2] = Math.atan2( m[4], m[0]); 1926 } 1927 return res; 1928} 1929 1930function setFromQuaternion( q ) 1931{ 1932 var ww = q[3]*q[3]; 1933 var xx = q[0]*q[0]; 1934 var yy = q[1]*q[1]; 1935 var zz = q[2]*q[2]; 1936 1937 return [ ww+xx-yy-zz, 2.0*(q[0]*q[1] - q[3]*q[2]), 2.0*(q[0]*q[2] + q[3]*q[1]), 0.0, 1938 2.0*(q[0]*q[1] + q[3]*q[2]), ww-xx+yy-zz, 2.0*(q[1]*q[2] - q[3]*q[0]), 0.0, 1939 2.0*(q[0]*q[2] - q[3]*q[1]), 2.0*(q[1]*q[2] + q[3]*q[0]), ww-xx-yy+zz, 0.0, 1940 0.0, 0.0, 0.0, 1.0 ]; 1941} 1942 1943function setPerspective( fovy, aspect, znear, zfar ) 1944{ 1945 var tan = Math.tan(fovy * Math.PI/180.0); 1946 var x = 1.0 / (tan*aspect); 1947 var y = 1.0 / (tan); 1948 var c = -(zfar + znear) / ( zfar - znear); 1949 var d = -(2.0 * zfar * znear) / (zfar - znear); 1950 1951 return [ x, 0.0, 0.0, 0.0, 1952 0.0, y, 0.0, 0.0, 1953 0.0, 0.0, c, d, 1954 0.0, 0.0, -1.0, 0.0 ]; 1955} 1956 1957function setLookAt( eye, tar, up ) 1958{ 1959 var dir = [ -tar[0]+eye[0], -tar[1]+eye[1], -tar[2]+eye[2] ]; 1960 1961 var m00 = dir[2]*up[1] - dir[1]*up[2]; 1962 var m01 = dir[0]*up[2] - dir[2]*up[0]; 1963 var m02 = dir[1]*up[0] - dir[0]*up[1]; 1964 var im = 1.0/Math.sqrt( m00*m00 + m01*m01 + m02*m02 ); 1965 m00 *= im; 1966 m01 *= im; 1967 m02 *= im; 1968 1969 var m04 = m02*dir[1] - m01*dir[2]; 1970 var m05 = m00*dir[2] - m02*dir[0];
1971 var m06 = m01*dir[0] - m00*dir[1]; 1972 im = 1.0/Math.sqrt( m04*m04 + m05*m05 + m06*m06 ); 1973 m04 *= im; 1974 m05 *= im; 1975 m06 *= im; 1976 1977 var m08 = dir[0]; 1978 var m09 = dir[1]; 1979 var m10 = dir[2]; 1980 im = 1.0/Math.sqrt( m08*m08 + m09*m09 + m10*m10 ); 1981 m08 *= im; 1982 m09 *= im; 1983 m10 *= im; 1984 1985 var m03 = -(m00*eye[0] + m01*eye[1] + m02*eye[2] ); 1986 var m07 = -(m04*eye[0] + m05*eye[1] + m06*eye[2] ); 1987 var m11 = -(m08*eye[0] + m09*eye[1] + m10*eye[2] ); 1988 1989 return [ m00, m01, m02, m03, 1990 m04, m05, m06, m07, 1991 m08, m09, m10, m11, 1992 0.0, 0.0, 0.0, 1.0 ]; 1993} 1994 1995 1996function setOrtho( left, right, bottom, top, znear, zfar ) 1997{ 1998 var x = 2.0 / (right - left); 1999 var y = 2.0 / (top - bottom); 2000 var a = (right + left) / (right - left); 2001 var b = (top + bottom) / (top - bottom); 2002 var c = -2.0 / (zfar - znear); 2003 var d = -(zfar + znear) / ( zfar - znear); 2004 2005 return [ x, 0.0, 0.0, a, 2006 0.0, y, 0.0, b, 2007 0.0, 0.0, c, d, 2008 0.0, 0.0, 0.0, 1.0 ]; 2009} 2010 2011function setTranslation( p ) 2012{ 2013 return [ 1.0, 0.0, 0.0, p[0], 2014 0.0, 1.0, 0.0, p[1], 2015 0.0, 0.0, 1.0, p[2], 2016 0.0, 0.0, 0.0, 1.0 ]; 2017} 2018 2019function setScale( s ) 2020{ 2021 return [ s[0], 0.0, 0.0, 0.0, 2022 0.0, s[1], 0.0, 0.0, 2023 0.0, 0.0, s[2], 0.0, 2024 0.0, 0.0, 0.0, 1.0]; 2025} 2026 2027function setProjection( fov, znear, zfar ) 2028{ 2029 var x = 2.0 / (fov[3]+fov[2]); 2030 var y = 2.0 / (fov[0]+fov[1]); 2031 var a = (fov[3]-fov[2]) / (fov[3]+fov[2]); 2032 var b = (fov[0]-fov[1]) / (fov[0]+fov[1]); 2033 var c = -(zfar + znear) / ( zfar - znear); 2034 var d = -(2.0*zfar*znear) / (zfar - znear); 2035 return [ x, 0.0, a, 0.0, 2036 0.0, y, b, 0.0, 2037 0.0, 0.0, c, d, 2038 0.0, 0.0, -1.0, 0.0 ]; 2039 // inverse is: 2040 //return mat4x4( 1.0/x, 0.0f, 0.0f, a/x, 2041 // 0.0f, 1.0/y, 0.0f, b/x, 2042 // 0.0f, 0.0f, 0.0f, -1.0, 2043 // 0.0f, 0.0f, 1.0f/d, c/d ); 2044} 2045 2046 2047function invertFast( m ) 2048{ 2049 var inv = [ 2050 2051 m[5] * m[10] * m[15] - 2052 m[5] * m[11] * m[14] - 2053 m[9] * m[6] * m[15] + 2054 m[9] * m[7] * m[14] + 2055 m[13] * m[6] * m[11] - 2056 m[13] * m[7] * m[10], 2057 2058 -m[1] * m[10] * m[15] + 2059 m[1] * m[11] * m[14] + 2060 m[9] * m[2] * m[15] - 2061 m[9] * m[3] * m[14] - 2062 m[13] * m[2] * m[11] + 2063 m[13] * m[3] * m[10], 2064 2065 m[1] * m[6] * m[15] - 2066 m[1] * m[7] * m[14] - 2067 m[5] * m[2] * m[15] + 2068 m[5] * m[3] * m[14] + 2069 m[13] * m[2] * m[7] - 2070 m[13] * m[3] * m[6], 2071 2072 -m[1] * m[6] * m[11] + 2073 m[1] * m[7] * m[10] + 2074 m[5] * m[2] * m[11] - 2075 m[5] * m[3] * m[10] - 2076 m[9] * m[2] * m[7] + 2077 m[9] * m[3] * m[6], 2078 2079 -m[4] * m[10] * m[15] + 2080 m[4] * m[11] * m[14] + 2081 m[8] * m[6] * m[15] - 2082 m[8] * m[7] * m[14] - 2083 m[12] * m[6] * m[11] + 2084 m[12] * m[7] * m[10], 2085 2086 m[0] * m[10] * m[15] - 2087 m[0] * m[11] * m[14] - 2088 m[8] * m[2] * m[15] + 2089 m[8] * m[3] * m[14] + 2090 m[12] * m[2] * m[11] - 2091 m[12] * m[3] * m[10], 2092 2093 -m[0] * m[6] * m[15] + 2094 m[0] * m[7] * m[14] + 2095 m[4] * m[2] * m[15] - 2096 m[4] * m[3] * m[14] - 2097 m[12] * m[2] * m[7] + 2098 m[12] * m[3] * m[6], 2099 2100 2101 m[0] * m[6] * m[11] - 2102 m[0] * m[7] * m[10] - 2103 m[4] * m[2] * m[11] + 2104 m[4] * m[3] * m[10] + 2105 m[8] * m[2] * m[7] - 2106 m[8] * m[3] * m[6], 2107 2108 2109 m[4] * m[9] * m[15] - 2110 m[4] * m[11] * m[13] - 2111 m[8] * m[5] * m[15] + 2112 m[8] * m[7] * m[13] + 2113 m[12] * m[5] * m[11] - 2114 m[12] * m[7] * m[9], 2115 2116 2117 2118 -m[0] * m[9] * m[15] + 2119 m[0] * m[11] * m[13] + 2120 m[8] * m[1] * m[15] - 2121 m[8] * m[3] * m[13] - 2122 m[12] * m[1] * m[11] + 2123 m[12] * m[3] * m[9], 2124 2125 m[0] * m[5] * m[15] - 2126 m[0] * m[7] * m[13] - 2127 m[4] * m[1] * m[15] + 2128 m[4] * m[3] * m[13] + 2129 m[12] * m[1] * m[7] - 2130 m[12] * m[3] * m[5], 2131 2132 -m[0] * m[5] * m[11] + 2133 m[0] * m[7] * m[9] + 2134 m[4] * m[1] * m[11] - 2135 m[4] * m[3] * m[9] - 2136 m[8] * m[1] * m[7] + 2137 m[8] * m[3] * m[5], 2138 2139 -m[4] * m[9] * m[14] + 2140 m[4] * m[10] * m[13] + 2141 m[8] * m[5] * m[14] - 2142 m[8] * m[6] * m[13] - 2143 m[12] * m[5] * m[10] + 2144 m[12] * m[6] * m[9], 2145 2146 m[0] * m[9] * m[14] - 2147 m[0] * m[10] * m[13] - 2148 m[8] * m[1] * m[14] + 2149 m[8] * m[2] * m[13] + 2150 m[12] * m[1] * m[10] - 2151 m[12] * m[2] * m[9], 2152 2153 -m[0] * m[5] * m[14] + 2154 m[0] * m[6] * m[13] + 2155 m[4] * m[1] * m[14] - 2156 m[4] * m[2] * m[13] - 2157 m[12] * m[1] * m[6] + 2158 m[12] * m[2] * m[5], 2159 2160 m[0] * m[5] * m[10] - 2161 m[0] * m[6] * m[9] - 2162 m[4] * m[1] * m[10] + 2163 m[4] * m[2] * m[9] + 2164 m[8] * m[1] * m[6] - 2165 m[8] * m[2] * m[5] ]; 2166 2167 var det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; 2168 2169 det = 1.0/det; 2170 2171 for( var i = 0; i<16; i++ ) inv[i] = inv[i] * det; 2172 2173 return inv; 2174} 2175 2176function matMul( a, b ) 2177{ 2178 var res = []; 2179 for( var i=0; i<4; i++ ) 2180 { 2181 var x = a[4*i+0]; 2182 var y = a[4*i+1]; 2183 var z = a[4*i+2]; 2184 var w = a[4*i+3]; 2185 2186 res[4*i+0] = x * b[ 0] + y * b[ 4] + z * b[ 8] + w * b[12]; 2187 res[4*i+1] = x * b[ 1] + y * b[ 5] + z * b[ 9] + w * b[13]; 2188 res[4*i+2] = x * b[ 2] + y * b[ 6] + z * b[10] + w * b[14]; 2189 res[4*i+3] = x * b[ 3] + y * b[ 7] + z * b[11] + w * b[15]; 2190 } 2191 2192 return res; 2193} 2194 2195function matMulpoint( m, v ) 2196{ 2197 return [ m[0]*v[0] + m[1]*v[1] + m[ 2]*v[2] + m[ 3], 2198 m[4]*v[0] + m[5]*v[1] + m[ 6]*v[2] + m[ 7], 2199 m[8]*v[0] + m[9]*v[1] + m[10]*v[2] + m[11] ]; 2200} 2201 2202function matMulvec( m, v ) 2203{ 2204 return [ m[0]*v[0] + m[1]*v[1] + m[ 2]*v[2], 2205 m[4]*v[0] + m[5]*v[1] + m[ 6]*v[2], 2206 m[8]*v[0] + m[9]*v[1] + m[10]*v[2] ]; 2207} 2208 2209 2210function bound3( infi ) 2211{ 2212 return [ infi, -infi, infi, -infi, infi, -infi ]; 2213} 2214 2215function bound3_include( a, p ) 2216{ 2217 return [ 2218 (p[0]<a[0]) ? p[0] : a[0], 2219 (p[0]>a[1]) ? p[0] : a[1], 2220 (p[1]<a[2]) ? p[1] : a[2], 2221 (p[1]>a[3]) ? p[1] : a[3], 2222 (p[2]<a[4]) ? p[2] : a[4], 2223 (p[2]>a[5]) ? p[2] : a[5] ]; 2224} 2225 2226function bound3_center( b ) 2227{ 2228 return [ 0.5*(b[0]+b[1]), 2229 0.5*(b[2]+b[3]), 2230 0.5*(b[4]+b[5]) ]; 2231} 2232 2233function bound3_radius( b ) 2234{ 2235 return [ 0.5*(b[1]-b[0]), 2236 0.5*(b[3]-b[2]), 2237 0.5*(b[5]-b[4]) ]; 2238} 2239//============================================================================== 2240// 2241// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 2242// 2243// piWebVR 2244// 2245//============================================================================== 2246 2247function WebVR( isVREnabledCallback, canvasElement ) 2248{ 2249 isVREnabledCallback(false); 2250} 2251 2252WebVR.prototype.IsSupported = function() 2253{ 2254 return false; 2255 //return this.mSupportVR; 2256} 2257 2258WebVR.prototype.GetData = function( id ) 2259{ 2260 return {}; 2261} 2262 2263WebVR.prototype.Enable = function( id ) 2264{ 2265} 2266 2267WebVR.prototype.Disable = function( id ) 2268{ 2269} 2270 2271WebVR.prototype.RequestAnimationFrame = function (id) 2272{ 2273} 2274 2275WebVR.prototype.IsPresenting = function (id) 2276{ 2277 return false; 2278} 2279 2280WebVR.prototype.Finish = function (id) 2281{ 2282} 2283 2284//============================================================================== 2285// 2286// piLibs 2015-2017 - http://www.iquilezles.org/www/material/piLibs/piLibs.htm 2287// 2288// piWebUtils 2289// 2290//============================================================================== 2291 2292 2293 2294function htmlEntities(str) 2295{ 2296 return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g,'''); 2297} 2298 2299function piDisableTouch() 2300{} 2301 2302var piGetTime = function ( timestamp ) 2303{ 2304 if (timestamp == 0) 2305 return ""; 2306 return new Date(timestamp * 1000).toISOString().substr(0, 10); 2307} 2308 2309function piGetCoords( obj ) 2310{ 2311 var x = 0; 2312 var y = 0; 2313 do 2314 { 2315 x += obj.offsetLeft; 2316 y += obj.offsetTop; 2317 }while( obj = obj.offsetParent ); 2318 2319 return { mX:x, mY:y }; 2320} 2321 2322function piGetMouseCoords( ev, canvasElement ) 2323{ 2324 var pos = piGetCoords(canvasElement ); 2325 var mcx = (ev.pageX - pos.mX) * canvasElement.width / canvasElement.offsetWidth; 2326 var mcy = canvasElement.height - (ev.pageY - pos.mY) * canvasElement.height / canvasElement.offsetHeight; 2327 2328 return { mX: mcx, mY: mcy }; 2329 2330} 2331 2332function piGetSourceElement( e ) 2333{ 2334 var ele = null; 2335 if( e.target ) ele = e.target; 2336 if( e.srcElement ) ele = e.srcElement; 2337 return ele; 2338} 2339 2340function piRequestFullScreen( ele ) 2341{} 2342 2343function piIsFullScreen() 2344{ 2345 return false; 2346} 2347 2348function piExitFullScreen() 2349{} 2350 2351function piIsMobile() 2352{ 2353 return false; 2354} 2355 2356function piCreateGlContext( cv, useAlpha, useDepth, usePreserveBuffer, useSupersampling ) 2357{
2358 var opts = { alpha: useAlpha, 2359 depth: useDepth, 2360 stencil: false, 2361 premultipliedAlpha: false, 2362 antialias: useSupersampling, 2363 preserveDrawingBuffer: usePreserveBuffer, 2364 powerPreference: "high-performance" }; // "low_power", "high_performance", "default" 2365 2366 var gl = null; 2367 if( gl === null) gl = cv.getContext( "webgl2", opts ); 2368 if( gl === null) gl = cv.getContext( "experimental-webgl2", opts ); 2369 if( gl === null) gl = cv.getContext( "webgl", opts ); 2370 if( gl === null) gl = cv.getContext( "experimental-webgl", opts ); 2371 2372 return gl; 2373} 2374 2375function piCreateAudioContext() 2376{ 2377 return null; 2378} 2379 2380function piHexColorToRGB(str) // "#ff3041" 2381{ 2382 var rgb = parseInt(str.slice(1), 16); 2383 var r = (rgb >> 16) & 255; 2384 var g = (rgb >> 8) & 255; 2385 var b = (rgb >> 0) & 255; 2386 return [r, g, b]; 2387} 2388 2389function piCreateFPSCounter() 2390{ 2391 var mFrame; 2392 var mTo; 2393 var mFPS; 2394 2395 var iReset = function( time ) 2396 { 2397 mFrame = 0; 2398 mTo = time; 2399 mFPS = 60.0; 2400 } 2401 2402 var iCount = function( time ) 2403 { 2404 mFrame++; 2405 2406 if( (time-mTo)>500.0 ) 2407 { 2408 mFPS = 1000.0*mFrame/(time-mTo); 2409 mFrame = 0; 2410 mTo = time; 2411 return true; 2412 } 2413 return false; 2414 } 2415 2416 var iGetFPS = function() 2417 { 2418 return mFPS; 2419 } 2420 2421 return { Reset : iReset, Count : iCount, GetFPS : iGetFPS }; 2422} 2423 2424function piCanMediaRecorded(canvas) 2425{ 2426 return true; 2427} 2428 2429function piCreateMediaRecorder(isRecordingCallback, canvas) 2430{ 2431 if (piCanMediaRecorded(canvas) == false) 2432 { 2433 return null; 2434 } 2435 2436 var options = { audioBitsPerSecond : 0, videoBitsPerSecond : 8000000 }; 2437 if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) options.mimeType = 'video/webm;codecs=h264'; 2438 else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9' )) options.mimeType = 'video/webm;codecs=vp9'; 2439 else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8' )) options.mimeType = 'video/webm;codecs=vp8'; 2440 else options.mimeType = 'video/webm;'; 2441 2442 var mediaRecorder = new MediaRecorder(canvas.captureStream(), options); 2443 var chunks = []; 2444 2445 mediaRecorder.ondataavailable = function(e) 2446 { 2447 if (e.data.size > 0) 2448 { 2449 chunks.push(e.data); 2450 } 2451 }; 2452 2453 mediaRecorder.onstart = function(){ 2454 isRecordingCallback( true ); 2455 }; 2456 2457 mediaRecorder.onstop = function() 2458 { 2459 isRecordingCallback( false ); 2460 }; 2461 2462 return mediaRecorder; 2463} 2464 2465function piExportToEXR(width, height, numComponents, type, bytes) 2466{ 2467 var bytesPerComponent = 0; 2468 if (type=="Uint") bytesPerComponent = 4; 2469 else if (type=="Half") bytesPerComponent = 2; 2470 else if (type=="Float") bytesPerComponent = 4; 2471 2472 var tHeader = 258 + (18 * numComponents + 1); 2473 var tTable = 8 * height; 2474 var tScanlines = height * (4 + 4 + (numComponents * bytesPerComponent * width)); 2475 var tTotal = tHeader + tTable + tScanlines; 2476 2477 var buffer = new ArrayBuffer(tTotal); 2478 var data = new DataView(buffer); 2479 2480 // Header 2481 { 2482 // Header : 4 bytes -> 0x76, 0x2f, 0x31, 0x01 2483 var c = 0; 2484 data.setUint8 (c++, 0x76); 2485 data.setUint8 (c++, 0x2f); 2486 data.setUint8 (c++, 0x31); 2487 data.setUint8 (c++, 0x01); 2488 2489 // Version : 4 bytes -> 2, 0, 0, 0 2490 data.setUint8 (c++, 0x02); 2491 data.setUint8 (c++, 0x0); 2492 data.setUint8 (c++, 0x0); 2493 data.setUint8 (c++, 0x0); 2494 2495 // Write channel info 2496 // Write attribute name : "channels" 2497 data.setUint8 (c++, 0x63); 2498 data.setUint8 (c++, 0x68); 2499 data.setUint8 (c++, 0x61); 2500 data.setUint8 (c++, 0x6e); 2501 data.setUint8 (c++, 0x6e); 2502 data.setUint8 (c++, 0x65); 2503 data.setUint8 (c++, 0x6c); 2504 data.setUint8 (c++, 0x73); 2505 data.setUint8 (c++, 0x0); 2506 2507 // Write attribute type : "chlist" 2508 data.setUint8 (c++, 0x63); 2509 data.setUint8 (c++, 0x68); 2510 data.setUint8 (c++, 0x6c); 2511 data.setUint8 (c++, 0x69); 2512 data.setUint8 (c++, 0x73); 2513 data.setUint8 (c++, 0x74); 2514 data.setUint8 (c++, 0x00); 2515 2516 // Write attribute size : 18 x 3 + 1 = 55 2517 var attribSize = 18 * numComponents + 1; 2518 data.setUint8 (c++, attribSize); 2519 data.setUint8 (c++, 0x00); 2520 data.setUint8 (c++, 0x00); 2521 data.setUint8 (c++, 0x00); 2522 2523 var i; 2524 for (i = 0; i < numComponents; i++) 2525 { 2526 // Attribute : "B" (42) "G" (47) "R" (52) 2527 if (i==0) data.setUint8 (c++, 0x42); 2528 else if (i==1) data.setUint8 (c++, 0x47); 2529 else if (i==2) data.setUint8 (c++, 0x52); 2530 data.setUint8 (c++, 0x00); 2531 2532 // Value : Float (2), Half (1), Uint (0) 2533 if (type=="Uint") data.setUint8 (c++, 0x00); 2534 else if (type=="Half") data.setUint8 (c++, 0x01); 2535 else if (type=="Float") data.setUint8 (c++, 0x02); 2536 data.setUint8 (c++, 0x00); 2537 data.setUint8 (c++, 0x00); 2538 data.setUint8 (c++, 0x00); 2539 2540 // Plinear 2541 data.setUint8 (c++, 0x01); 2542 2543 // Reserved 2544 data.setUint8 (c++, 0x00); 2545 data.setUint8 (c++, 0x00); 2546 data.setUint8 (c++, 0x00); 2547 2548 // X sampling 2549 data.setUint8 (c++, 0x01); 2550 data.setUint8 (c++, 0x00); 2551 data.setUint8 (c++, 0x00); 2552 data.setUint8 (c++, 0x00); 2553 2554 // Y sampling 2555 data.setUint8 (c++, 0x01); 2556 data.setUint8 (c++, 0x00); 2557 data.setUint8 (c++, 0x00); 2558 data.setUint8 (c++, 0x00); 2559 } 2560 // End attribute 2561 data.setUint8 (c++, 0x00); 2562 2563 // Write attribute name : "compression" 2564 data.setUint8 (c++, 0x63); 2565 data.setUint8 (c++, 0x6f); 2566 data.setUint8 (c++, 0x6d); 2567 data.setUint8 (c++, 0x70); 2568 data.setUint8 (c++, 0x72); 2569 data.setUint8 (c++, 0x65); 2570 data.setUint8 (c++, 0x73); 2571 data.setUint8 (c++, 0x73); 2572 data.setUint8 (c++, 0x69); 2573 data.setUint8 (c++, 0x6f); 2574 data.setUint8 (c++, 0x6e); 2575 data.setUint8 (c++, 0x00); 2576 2577 // Write attribute type : "compression" 2578 data.setUint8 (c++, 0x63); 2579 data.setUint8 (c++, 0x6f); 2580 data.setUint8 (c++, 0x6d); 2581 data.setUint8 (c++, 0x70); 2582 data.setUint8 (c++, 0x72); 2583 data.setUint8 (c++, 0x65); 2584 data.setUint8 (c++, 0x73); 2585 data.setUint8 (c++, 0x73); 2586 data.setUint8 (c++, 0x69); 2587 data.setUint8 (c++, 0x6f); 2588 data.setUint8 (c++, 0x6e); 2589 data.setUint8 (c++, 0x00); 2590 2591 // Write attribute size : "1" 2592 data.setUint8 (c++, 0x01); 2593 data.setUint8 (c++, 0x00); 2594 data.setUint8 (c++, 0x00); 2595 data.setUint8 (c++, 0x00); 2596 2597 // Write attribute value : "0" (None) 2598 data.setUint8 (c++, 0x00); 2599 2600 // datawindow 2601 data.setUint8 (c++, 0x64); 2602 data.setUint8 (c++, 0x61); 2603 data.setUint8 (c++, 0x74); 2604 data.setUint8 (c++, 0x61); 2605 data.setUint8 (c++, 0x57); 2606 data.setUint8 (c++, 0x69); 2607 data.setUint8 (c++, 0x6e); 2608 data.setUint8 (c++, 0x64); 2609 data.setUint8 (c++, 0x6f); 2610 data.setUint8 (c++, 0x77); 2611 data.setUint8 (c++, 0x00); 2612 2613 // box2i 2614 data.setUint8 (c++, 0x62); 2615 data.setUint8 (c++, 0x6f); 2616 data.setUint8 (c++, 0x78); 2617 data.setUint8 (c++, 0x32); 2618 data.setUint8 (c++, 0x69); 2619 data.setUint8 (c++, 0x00); 2620 2621 // size 16 2622 data.setUint8 (c++, 0x10); 2623 data.setUint8 (c++, 0x00); 2624 data.setUint8 (c++, 0x00); 2625 data.setUint8 (c++, 0x00); 2626 2627 // value 0 0 3 2 2628 data.setUint8 (c++, 0x00); 2629 data.setUint8 (c++, 0x00); 2630 data.setUint8 (c++, 0x00); 2631 data.setUint8 (c++, 0x00); 2632 2633 data.setUint8 (c++, 0x00); 2634 data.setUint8 (c++, 0x00); 2635 data.setUint8 (c++, 0x00); 2636 data.setUint8 (c++, 0x00); 2637 2638 data.setUint32 (c, width-1, true); 2639 c += 4; 2640 2641 data.setUint32 (c, height-1, true); 2642 c += 4; 2643 2644 // displayWindow 2645 data.setUint8 (c++, 0x64); 2646 data.setUint8 (c++, 0x69); 2647 data.setUint8 (c++, 0x73); 2648 data.setUint8 (c++, 0x70); 2649 data.setUint8 (c++, 0x6c); 2650 data.setUint8 (c++, 0x61); 2651 data.setUint8 (c++, 0x79); 2652 data.setUint8 (c++, 0x57); 2653 data.setUint8 (c++, 0x69); 2654 data.setUint8 (c++, 0x6e); 2655 data.setUint8 (c++, 0x64); 2656 data.setUint8 (c++, 0x6f); 2657 data.setUint8 (c++, 0x77); 2658 data.setUint8 (c++, 0x00); 2659 2660 // box2i 2661 data.setUint8 (c++, 0x62); 2662 data.setUint8 (c++, 0x6f); 2663 data.setUint8 (c++, 0x78); 2664 data.setUint8 (c++, 0x32); 2665 data.setUint8 (c++, 0x69); 2666 data.setUint8 (c++, 0x00); 2667 2668 // size 16 2669 data.setUint8 (c++, 0x10); 2670 data.setUint8 (c++, 0x00); 2671 data.setUint8 (c++, 0x00); 2672 data.setUint8 (c++, 0x00); 2673 2674 // value 0 0 3 2 2675 data.setUint8 (c++, 0x00); 2676 data.setUint8 (c++, 0x00); 2677 data.setUint8 (c++, 0x00); 2678 data.setUint8 (c++, 0x00); 2679 2680 data.setUint8 (c++, 0x00); 2681 data.setUint8 (c++, 0x00); 2682 data.setUint8 (c++, 0x00); 2683 data.setUint8 (c++, 0x00); 2684 2685 data.setUint32 (c, width-1, true); 2686 c += 4; 2687 2688 data.setUint32 (c, height-1, true); 2689 c += 4; 2690 2691 // lineOrder 2692 data.setUint8 (c++, 0x6c); 2693 data.setUint8 (c++, 0x69); 2694 data.setUint8 (c++, 0x6e); 2695 data.setUint8 (c++, 0x65); 2696 data.setUint8 (c++, 0x4f); 2697 data.setUint8 (c++, 0x72); 2698 data.setUint8 (c++, 0x64); 2699 data.setUint8 (c++, 0x65); 2700 data.setUint8 (c++, 0x72); 2701 data.setUint8 (c++, 0x00); 2702 2703 // lineOrder 2704 data.setUint8 (c++, 0x6c); 2705 data.setUint8 (c++, 0x69); 2706 data.setUint8 (c++, 0x6e); 2707 data.setUint8 (c++, 0x65); 2708 data.setUint8 (c++, 0x4f); 2709 data.setUint8 (c++, 0x72); 2710 data.setUint8 (c++, 0x64); 2711 data.setUint8 (c++, 0x65); 2712 data.setUint8 (c++, 0x72); 2713 data.setUint8 (c++, 0x00); 2714 2715 // size 2716 data.setUint8 (c++, 0x01); 2717 data.setUint8 (c++, 0x00); 2718 data.setUint8 (c++, 0x00); 2719 data.setUint8 (c++, 0x00); 2720 2721 // value 2722 data.setUint8 (c++, 0x00); 2723 2724 // PixelAspectRatio 2725 data.setUint8 (c++, 0x70); 2726 data.setUint8 (c++, 0x69); 2727 data.setUint8 (c++, 0x78); 2728 data.setUint8 (c++, 0x65); 2729 data.setUint8 (c++, 0x6c); 2730 data.setUint8 (c++, 0x41); 2731 data.setUint8 (c++, 0x73); 2732 data.setUint8 (c++, 0x70); 2733 data.setUint8 (c++, 0x65); 2734 data.setUint8 (c++, 0x63); 2735 data.setUint8 (c++, 0x74); 2736 data.setUint8 (c++, 0x52); 2737 data.setUint8 (c++, 0x61); 2738 data.setUint8 (c++, 0x74); 2739 data.setUint8 (c++, 0x69); 2740 data.setUint8 (c++, 0x6f); 2741 data.setUint8 (c++, 0x00); 2742 2743 // float 2744 data.setUint8 (c++, 0x66); 2745 data.setUint8 (c++, 0x6c); 2746 data.setUint8 (c++, 0x6f); 2747 data.setUint8 (c++, 0x61); 2748 data.setUint8 (c++, 0x74); 2749 data.setUint8 (c++, 0x00); 2750 2751 // size 4 2752 data.setUint8 (c++, 0x04); 2753 data.setUint8 (c++, 0x00); 2754 data.setUint8 (c++, 0x00); 2755 data.setUint8 (c++, 0x00); 2756 2757 // value 1.0 2758 data.setUint8 (c++, 0x00); 2759 data.setUint8 (c++, 0x00); 2760 data.setUint8 (c++, 0x80); 2761 data.setUint8 (c++, 0x3f); 2762 2763 // screenWindowCenter 2764 data.setUint8 (c++, 0x73); 2765 data.setUint8 (c++, 0x63); 2766 data.setUint8 (c++, 0x72); 2767 data.setUint8 (c++, 0x65); 2768 data.setUint8 (c++, 0x65); 2769 data.setUint8 (c++, 0x6e); 2770 data.setUint8 (c++, 0x57); 2771 data.setUint8 (c++, 0x69); 2772 data.setUint8 (c++, 0x6e); 2773 data.setUint8 (c++, 0x64); 2774 data.setUint8 (c++, 0x6f); 2775 data.setUint8 (c++, 0x77); 2776 data.setUint8 (c++, 0x43); 2777 data.setUint8 (c++, 0x65); 2778 data.setUint8 (c++, 0x6e); 2779 data.setUint8 (c++, 0x74); 2780 data.setUint8 (c++, 0x65); 2781 data.setUint8 (c++, 0x72); 2782 data.setUint8 (c++, 0x00); 2783 2784 // v2f 2785 data.setUint8 (c++, 0x76); 2786 data.setUint8 (c++, 0x32); 2787 data.setUint8 (c++, 0x66); 2788 data.setUint8 (c++, 0x00); 2789 2790 // size 8 2791 data.setUint8 (c++, 0x08); 2792 data.setUint8 (c++, 0x00); 2793 data.setUint8 (c++, 0x00); 2794 data.setUint8 (c++, 0x00); 2795 2796 // value 0 0 2797 data.setUint8 (c++, 0x00); 2798 data.setUint8 (c++, 0x00); 2799 data.setUint8 (c++, 0x00); 2800 data.setUint8 (c++, 0x00); 2801 2802 data.setUint8 (c++, 0x00); 2803 data.setUint8 (c++, 0x00); 2804 data.setUint8 (c++, 0x00); 2805 data.setUint8 (c++, 0x00); 2806 2807 // screenWindowWidth 2808 data.setUint8 (c++, 0x73); 2809 data.setUint8 (c++, 0x63); 2810 data.setUint8 (c++, 0x72); 2811 data.setUint8 (c++, 0x65); 2812 data.setUint8 (c++, 0x65); 2813 data.setUint8 (c++, 0x6e); 2814 data.setUint8 (c++, 0x57); 2815 data.setUint8 (c++, 0x69); 2816 data.setUint8 (c++, 0x6e); 2817 data.setUint8 (c++, 0x64); 2818 data.setUint8 (c++, 0x6f); 2819 data.setUint8 (c++, 0x77); 2820 data.setUint8 (c++, 0x57); 2821 data.setUint8 (c++, 0x69); 2822 data.setUint8 (c++, 0x64); 2823 data.setUint8 (c++, 0x74); 2824 data.setUint8 (c++, 0x68); 2825 data.setUint8 (c++, 0x00); 2826 2827 // float 2828 data.setUint8 (c++, 0x66); 2829 data.setUint8 (c++, 0x6c); 2830 data.setUint8 (c++, 0x6f); 2831 data.setUint8 (c++, 0x61); 2832 data.setUint8 (c++, 0x74); 2833 data.setUint8 (c++, 0x00); 2834 2835 // size 2836 data.setUint8 (c++, 0x04); 2837 data.setUint8 (c++, 0x00); 2838 data.setUint8 (c++, 0x00); 2839 data.setUint8 (c++, 0x00); 2840 2841 // value 2842 data.setUint8 (c++, 0x00); 2843 data.setUint8 (c++, 0x00); 2844 data.setUint8 (c++, 0x80); 2845 data.setUint8 (c++, 0x3f); 2846 2847 // End of header 2848 data.setUint8 (c++, 0x00); 2849 } 2850 2851 // Scanline table 2852 var initc = c + height * 8; 2853 for (var scanline = 0 ; scanline < height ; scanline ++) 2854 { 2855 var jump = initc + scanline * (8 + width * bytesPerComponent * numC
2855omponents); 2856 data.setUint32 (c, jump, true); 2857 c += 4; 2858 2859 data.setUint32 (c, 0x00, true); 2860 c += 4; 2861 } 2862 2863 // Scanlines 2864 for (var scanline = 0 ; scanline < height ; scanline ++) 2865 { 2866 // Scanline 2867 data.setUint32(c, scanline, true); 2868 c += 4; 2869 2870 // size 24 2871 var size = width * numComponents * bytesPerComponent; 2872 data.setUint32(c, size, true); 2873 c += 4; 2874 2875 var numComponentsSource = 4; // number of components in the SOURCE image 2876 for (var component = 0; component < numComponents ; component ++) 2877 { 2878 for (var pixel = 0 ; pixel < width ; pixel ++) 2879 { 2880 // flip vertical, so we read OpenGL buffers without JS image flipping 2881 var v = bytes[(height-1-scanline) * width *numComponentsSource + pixel * numComponentsSource + (2-component)]; 2882 if (type=="Float") data.setFloat32(c, v, true); 2883 else if (type=="Half") data.setUint16(c, v, true); 2884 2885 c += bytesPerComponent; 2886 } 2887 } 2888 } 2889 2890 return new Blob([buffer], {type: 'application/octet-stream'}); 2891} 2892 2893 2894function piExportToWAV(numSamples, rate, bits, numChannels, words) 2895{ 2896 let numBytes = numSamples * numChannels * bits/8; 2897 2898 let buffer = new ArrayBuffer(44 + numBytes); 2899 let data = new DataView(buffer); 2900 2901 { 2902 data.setUint32( 0, 0x46464952, true ); // RIFF 2903 data.setUint32( 4, numBytes + 36, true); 2904 { 2905 data.setUint32( 8, 0x45564157, true ); // WAV_WAVE 2906 data.setUint32( 12, 0x20746D66, true ); // WAV_FMT 2907 { 2908 data.setUint32( 16, 16, true); 2909 data.setUint16( 20, 1, true ); // WAV_FORMAT_PCM 2910 data.setUint16( 22, numChannels, true); 2911 data.setUint32( 24, rate, true); 2912 data.setUint32( 28, rate*numChannels*bits / 8, true); 2913 data.setUint16( 32, numChannels*bits / 8, true); 2914 data.setUint16( 34, bits, true); 2915 } 2916 2917 data.setUint32( 36, 0x61746164, true); // WAV_DATA 2918 { 2919 data.setUint32( 40, numBytes, true); 2920 let numWords = numSamples * numChannels; 2921 for(let i=0; i<numWords; i++ ) 2922 { 2923 data.setInt16( 44 + i*2, words[i], true ); 2924 } 2925 } 2926 } 2927 } 2928 2929 2930 return new Blob([buffer], {type: 'application/octet-stream'}); 2931} 2932 2933function piTriggerDownload(name, blob) 2934{}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.