123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 |
- jQuery.glCheckError = function( gl, error_log )
- {
- var error = gl.getError();
- if (error != gl.NO_ERROR)
- {
- var error_str = "GL Error: " + error + " " + gl.enum_strings[error];
- if ( typeof error_log === 'function' )
- {
- error_log( error_str );
- }
- throw error_str;
- }
- }
- // jQuery.glProgram = function( gl, config, complete )
- //
- // Example config:
- //
- // var g_BumpReflectProgram =
- // {
- // VertexProgramURL: '/shaders/bump_reflect.vs',
- // FragmentProgramURL: '/shaders/bump_reflect.fs',
- // ErrorLog: error_log,
- // };
- jQuery.glProgram = function( gl, config, complete )
- {
- this.Program = null;
- this.UniformLocations = { };
- this.AttributeIndices = [];
- this.Uniforms = [];
- this.UniformTypes = { };
- this.Attributes = [];
- this.AttributeTypes = { };
- this.ErrorLog = config.error_log;
- this.BoundTextureCount = 0;
- this.Use = function()
- {
- gl.useProgram( this.Program );
- this.BoundTextureCount = 0;
- }
- this.BindModel = function( model, bindings )
- {
- var attribute_ndx = this.AttributeIndices;
- gl.bindBuffer(gl.ARRAY_BUFFER, model.VertexBuffer );
- for ( var model_stream_name in bindings )
- {
- var program_stream_name = bindings[ model_stream_name ];
- var program_attribute = this.AttributeIndices[ program_stream_name ];
- var model_stream_offset = model.VertexStreamBufferOffsets[ model_stream_name ];
- var model_stream_stride = model.VertexStreamBufferStrides[ model_stream_name ];
- var model_stream_type = model.VertexStreamBufferGLTypes[ model_stream_name ];
- gl.vertexAttribPointer( program_attribute, model_stream_stride, model_stream_type, false, 0, model_stream_offset );
- gl.enableVertexAttribArray( program_attribute );
- }
- gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, model.IndexBuffer );
- $.glCheckError( gl, this.ErrorLog );
- this.Model = model;
- }
- this.BindUniform = function( uniform_name, value )
- {
- var uniform_type = this.UniformTypes[ uniform_name ];
-
- switch (uniform_type)
- {
- case 'mat4':
- {
- gl.uniformMatrix4fv( this.UniformLocations[ uniform_name ], gl.FALSE, new Float32Array( value ) );
- }
- break;
- case 'sampler2D':
- {
- gl.activeTexture( gl[ 'TEXTURE' + this.BoundTextureCount ] );
-
- if ( value instanceof jQuery.glTexture )
- {
- gl.bindTexture( gl.TEXTURE_2D, value.Texture );
- }
- else
- {
- gl.bindTexture( gl.TEXTURE_2D, value );
- }
- gl.uniform1i( this.UniformLocations[ uniform_name ], this.BoundTextureCount );
- this.BoundTextureCount++;
- }
- break;
- case 'samplerCube':
- {
- gl.activeTexture( gl[ 'TEXTURE' + this.BoundTextureCount ] );
- gl.bindTexture( gl.TEXTURE_CUBE_MAP, value );
- gl.uniform1i( this.UniformLocations[ uniform_name ], this.BoundTextureCount );
- this.BoundTextureCount++;
- }
- break;
- }
- }
- this.DrawModel = function()
- {
- var model = this.Model; // Model must be bound with BindModel first.
- gl.drawElements( gl.TRIANGLES, model.IndexCount, model.IndexStreamGLType, 0 );
- }
- this.CreateBestVertexBindings = function( model )
- {
- var bindings = new Object();
- for (var i=0;i<model.VertexStreamNames.length;i++)
- {
- var vertex_stream_name = model.VertexStreamNames[i];
- var best_dist = 1000;
- for (var j=0;j<this.Attributes.length;j++)
- {
- var attribute_name = this.Attributes[j];
- var dist = vertex_stream_name.LD( attribute_name );
- if ( dist < best_dist )
- {
- bindings[ vertex_stream_name ] = attribute_name;
- best_dist = dist;
- }
- }
- }
- return (bindings);
- }
- var vertex_shader = null;
- var fragment_shader = null;
- var CompileShader = function( type, source )
- {
- var shader = gl.createShader(type);
- if (shader == null)
- {
- return null;
- }
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
- {
- var infoLog = gl.getShaderInfoLog(shader);
- output("Error compiling shader:\n" + infoLog);
- gl.deleteShader(shader);
- return null;
- }
- return shader;
- }
- var TryErrorLog = function( msg )
- {
- if ( typeof config.ErrorLog !== 'function' ) return;
- config.ErrorLog( msg );
- }
- var TryBuildProgram = function()
- {
- if ( vertex_shader == null ) return;
- if ( fragment_shader == null ) return;
- this.Program = gl.createProgram();
- if (this.Program == null)
- {
- TryErrorLog("Could not create GL program");
- return;
- }
- gl.attachShader( this.Program, vertex_shader );
- gl.attachShader( this.Program, fragment_shader );
- for (var i=0;i<this.Attributes.length;i++)
- {
- var attribute_name = this.Attributes[i];
- this.AttributeIndices[ attribute_name ] = i;
- gl.bindAttribLocation( this.Program, i, attribute_name );
- }
- gl.linkProgram( this.Program );
- var linked = gl.getProgramParameter( this.Program, gl.LINK_STATUS );
- if (!linked)
- {
- var infoLog = gl.getProgramInfoLog(this.Program);
- TryErrorLog("GL program link failed: " + infoLog);
- gl.deleteProgram( this.Program );
- this.Program = null;
- return;
- }
- for (var i=0;i<this.Uniforms.length;i++)
- {
- var uniform_name = this.Uniforms[i];
- this.UniformLocations[ uniform_name ] = gl.getUniformLocation( this.Program, uniform_name );
- }
- $.glCheckError( gl, config.error_log );
- if ( typeof complete === 'function' ) complete( this );
- }
- var AddUniforms = function( source )
- {
- var uniform_match = /uniform\s+(\w+)\s+(\w+)\s*;/g
- var uniforms = source.match( uniform_match );
- for (var i=0;i<uniforms.length;i++)
- {
- var uniform = uniforms[i].split( uniform_match );
- var uniform_type = uniform[1];
- var uniform_name = uniform[2];
-
- this.Uniforms.push( uniform_name );
- this.UniformTypes[ uniform_name ] = uniform_type;
- }
- }
- var AddAttributes = function( source )
- {
- var attribute_match = /attribute\s+(\w+)\s+(\w+)\s*;/g
- var attributes = source.match( attribute_match );
- for (var i=0;i<attributes.length;i++)
- {
- var attribute = attributes[i].split( attribute_match );
- var attribute_type = attribute[1];
- var attribute_name = attribute[2];
-
- this.Attributes.push( attribute_name );
- this.AttributeTypes[ attribute_name ] = attribute_type;
- }
- }
- var LoadVertexShader = function( source )
- {
- vertex_shader = CompileShader.apply( this, [ gl.VERTEX_SHADER, source ] );
- AddUniforms.apply( this, [ source ] );
- AddAttributes.apply( this, [ source ] );
- TryBuildProgram.apply( this );
- }
- var LoadFragmentShader = function( source )
- {
- fragment_shader = CompileShader.apply( this, [ gl.FRAGMENT_SHADER, source ] );
-
- AddUniforms.apply( this, [ source ] );
- TryBuildProgram.apply( this );
- }
- var that = this;
- this.get = function( url, fn )
- {
- var request = new XMLHttpRequest();
- request.open( "GET", url, true );
- request.send( null );
- fn( request.responseText );
- }
- this.get( config.VertexProgramURL, function( source ) { LoadVertexShader.apply( that, arguments ); } );
- this.get( config.FragmentProgramURL, function( source ) { LoadFragmentShader.apply( that, arguments ); } );
- // $.get( config.VertexProgramURL, function( source ) { LoadVertexShader.apply( that, arguments ); } );
- // $.get( config.FragmentProgramURL, function( source ) { LoadFragmentShader.apply( that, arguments ); } );
- }
- // jQuery.glModel = function( gl, model_url, complete )
- //
- // Model JSON format:
- // {
- // VertexStreams: [
- // {
- // Name: "position",
- // Type: "float",
- // Stride: 3,
- // Stream: [ 1.0, 1.0, 1.0, ... ]
- // }
- // ,...
- // ]
- // Indices:
- // {
- // Type: "uint16_t",
- // Stream: [ 0, 1, 2, 2, 3, 4, ... ]
- // }
- // }
- // }
- jQuery.glModel = function( gl, model_url, complete )
- {
- this.VertexStreamNames = [];
- this.VertexStreamBuffers = [];
- this.VertexStreamBufferOffsets = [];
- this.VertexStreamBufferStrides = [];
- this.VertexStreamBufferGLTypes = [];
- this.VertexBuffer = null;
- this.IndexStreamBuffer = null;
- this.IndexStreamGLType = null;
- this.IndexBuffer = null;
- this.IndexCount = 0;
- var LoadModel = function( source )
- {
- var CreateArrayByStdType = function( type, source )
- {
- if (type == 'float')
- {
- return new Float32Array( source );
- }
- else if (type == 'uint16_t')
- {
- return new Uint16Array( source );
- }
- else if (type == 'uint32_t')
- {
- return new Uint32Array( source );
- }
- else if (type == 'uint8_t')
- {
- return new Uint8Array( source );
- }
- }
- var GLTypeByStdType = function( type )
- {
- if (type == 'float')
- {
- return gl.FLOAT;
- }
- else if (type == 'uint16_t')
- {
- return gl.UNSIGNED_SHORT;
- }
- else if (type == 'uint32_t')
- {
- return gl.UNSIGNED_INT;
- }
- else if (type == 'uint8_t')
- {
- return gl.UNSIGNED_BYTE;
- }
- }
- var vertex_stream_count = source.VertexStreams.length;
- var vertex_buffer_size = 0;
- for (var i=0;i<vertex_stream_count;i++)
- {
- var stream_source = source.VertexStreams[i];
- var stream_name = stream_source.Name;
- var stream_buffer = CreateArrayByStdType( stream_source.Type, stream_source.Stream );
- var stream_stride = stream_source.Stride;
- var stream_type = stream_source.Type;
- var stream_gl_type = GLTypeByStdType( stream_type );
- this.VertexStreamBuffers[i] = stream_buffer;
- this.VertexStreamNames[i] = stream_name;
- this.VertexStreamBufferOffsets[ stream_name ] = vertex_buffer_size;
- this.VertexStreamBufferStrides[ stream_name ] = stream_stride;
- this.VertexStreamBufferGLTypes[ stream_name ] = stream_gl_type;
- if ( stream_buffer )
- {
- vertex_buffer_size += stream_buffer.byteLength;
- }
- }
- this.VertexBuffer = gl.createBuffer();
- gl.bindBuffer( gl.ARRAY_BUFFER, this.VertexBuffer );
- gl.bufferData( gl.ARRAY_BUFFER, vertex_buffer_size, gl.STATIC_DRAW );
- for (var i=0;i<vertex_stream_count;i++)
- {
- var stream_source = source.VertexStreams[i];
- var stream_name = stream_source.Name;
- gl.bufferSubData( gl.ARRAY_BUFFER, this.VertexStreamBufferOffsets[ stream_name ], this.VertexStreamBuffers[i] );
- }
- this.IndexBuffer = gl.createBuffer();
- this.IndexStreamBuffer = CreateArrayByStdType( source.Indices.Type, source.Indices.Stream );
- this.IndexStreamGLType = GLTypeByStdType( source.Indices.Type );
- this.IndexCount = source.Indices.Stream.length;
- gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, this.IndexBuffer );
- gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, this.IndexStreamBuffer, gl.STATIC_DRAW );
- if ( typeof complete === 'function' ) complete( this );
- }
- var that = this;
- $.ajax({
- url: model_url,
- dataType: 'json',
- mimeType: 'application/json',
- success: function( source ) { LoadModel.apply( that, arguments ); }
- });
- //$.getJSON( model_url, function( source ) { LoadModel.apply( that, arguments ); } );
- }
- jQuery.glModel2 = function( gl, model, complete )
- {
- this.VertexStreamNames = [];
- this.VertexStreamBuffers = [];
- this.VertexStreamBufferOffsets = [];
- this.VertexStreamBufferStrides = [];
- this.VertexStreamBufferGLTypes = [];
- this.VertexBuffer = null;
- this.IndexStreamBuffer = null;
- this.IndexStreamGLType = null;
- this.IndexBuffer = null;
- this.IndexCount = 0;
- var LoadModel = function( source )
- {
- var CreateArrayByStdType = function( type, source )
- {
- if (type == 'float')
- {
- return new Float32Array( source );
- }
- else if (type == 'uint16_t')
- {
- return new Uint16Array( source );
- }
- else if (type == 'uint32_t')
- {
- return new Uint32Array( source );
- }
- else if (type == 'uint8_t')
- {
- return new Uint8Array( source );
- }
- }
- var GLTypeByStdType = function( type )
- {
- if (type == 'float')
- {
- return gl.FLOAT;
- }
- else if (type == 'uint16_t')
- {
- return gl.UNSIGNED_SHORT;
- }
- else if (type == 'uint32_t')
- {
- return gl.UNSIGNED_INT;
- }
- else if (type == 'uint8_t')
- {
- return gl.UNSIGNED_BYTE;
- }
- }
- var vertex_stream_count = source.VertexStreams.length;
- var vertex_buffer_size = 0;
- for (var i=0;i<vertex_stream_count;i++)
- {
- var stream_source = source.VertexStreams[i];
- var stream_name = stream_source.Name;
- var stream_buffer = CreateArrayByStdType( stream_source.Type, stream_source.Stream );
- var stream_stride = stream_source.Stride;
- var stream_type = stream_source.Type;
- var stream_gl_type = GLTypeByStdType( stream_type );
- this.VertexStreamBuffers[i] = stream_buffer;
- this.VertexStreamNames[i] = stream_name;
- this.VertexStreamBufferOffsets[ stream_name ] = vertex_buffer_size;
- this.VertexStreamBufferStrides[ stream_name ] = stream_stride;
- this.VertexStreamBufferGLTypes[ stream_name ] = stream_gl_type;
- if ( stream_buffer )
- {
- vertex_buffer_size += stream_buffer.byteLength;
- }
- }
- this.VertexBuffer = gl.createBuffer();
- gl.bindBuffer( gl.ARRAY_BUFFER, this.VertexBuffer );
- gl.bufferData( gl.ARRAY_BUFFER, vertex_buffer_size, gl.STATIC_DRAW );
- for (var i=0;i<vertex_stream_count;i++)
- {
- var stream_source = source.VertexStreams[i];
- var stream_name = stream_source.Name;
- gl.bufferSubData( gl.ARRAY_BUFFER, this.VertexStreamBufferOffsets[ stream_name ], this.VertexStreamBuffers[i] );
- }
- this.IndexBuffer = gl.createBuffer();
- this.IndexStreamBuffer = CreateArrayByStdType( source.Indices.Type, source.Indices.Stream );
- this.IndexStreamGLType = GLTypeByStdType( source.Indices.Type );
- this.IndexCount = source.Indices.Stream.length;
- gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, this.IndexBuffer );
- gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, this.IndexStreamBuffer, gl.STATIC_DRAW );
- if ( typeof complete === 'function' ) complete( this );
- }
- var that = this;
- /*
- $.ajax({
- url: model_url,
- dataType: 'json',
- mimeType: 'application/json',
- success: function( source ) { LoadModel.apply( that, arguments ); }
- });
- */
- LoadModel.apply( this, [ model ] );
- }
- // jQuery.glTexture = function( gl, config, complete )
- //
- // Example config:
- //
- // var g_BumpTextureConfig =
- // {
- // Type: 'TEXTURE_2D',
- // ImageURL: './images/bump.jpg',
- // TexParameters:
- // {
- // TEXTURE_MIN_FILTER: 'LINEAR',
- // TEXTURE_MAG_FILTER: 'LINEAR',
- // TEXTURE_WRAP_S: 'REPEAT',
- // TEXTURE_WRAP_T: 'REPEAT'
- // },
- // PixelStoreParameters:
- // {
- // UNPACK_FLIP_Y_WEBGL: true
- // }
- // };
- jQuery.glTexture = function( gl, config, complete )
- {
- this.Texture = gl.createTexture();
- this.ErrorLog = config.ErrorLog;
- var texture_type = gl[ config.Type ];
- var images_remaining;
- var that = this;
- if ( this.Texture == null )
- {
- return null;
- }
- gl.bindTexture( texture_type, this.Texture );
- for ( var pname in config.TexParameters )
- {
- var pvalue = config.TexParameters[ pname ];
- var parameter_name = gl[ pname ];
- var parameter_value = gl[ pvalue ];
- gl.texParameteri( texture_type, parameter_name, parameter_value );
- $.glCheckError( gl, this.ErrorLog );
- }
- var ImageLoaded = function( image, image_type, mip )
- {
- gl.bindTexture( texture_type, this.Texture );
- $.glCheckError( gl, this.ErrorLog );
- for ( var pname in config.PixelStoreParameters )
- {
- var parameter_name = gl[ pname ];
- var parameter_value = config.PixelStoreParameters[ pname ];
- gl.pixelStorei( parameter_name, parameter_value );
- $.glCheckError( gl, this.ErrorLog );
- }
- gl.texImage2D( image_type, mip, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image );
- $.glCheckError( gl, this.ErrorLog );
- if ( texture_type === gl.TEXTURE_CUBE_MAP && image_type === gl.TEXTURE_CUBE_MAP_NEGATIVE_Z )
- gl.generateMipmap( texture_type );
- if ( texture_type === gl.TEXTURE_2D && config.MipURL == undefined )
- gl.generateMipmap( texture_type );
- $.glCheckError( gl, this.ErrorLog );
- images_remaining--;
- if ( images_remaining == 0 )
- {
- if ( typeof complete === 'function' ) complete( this );
- }
- }
- var LoadImage = function( src, image_type, mip )
- {
- var image = new Image();
- image.onload = function() { ImageLoaded.apply( that, [ image, image_type, mip ] ); };
- image.src = src;
- }
- if ( typeof config.ImageURL == 'string' )
- {
- images_remaining = 1;
-
- if ( config.MipURL !== undefined )
- {
- images_remaining += config.MipURL.length;
- }
-
- LoadImage( config.ImageURL, gl[ config.Type ], 0 );
- if ( config.MipURL !== undefined )
- {
- for (var i=0;i<config.MipURL.length;i++)
- {
- LoadImage( config.MipURL[i], gl[ config.Type ], i + 1 );
- }
- }
- }
- else
- {
- images_remaining = config.ImageURL.length;
- for (var i=0;i<config.ImageURL.length;i++)
- {
- LoadImage( config.ImageURL[i], gl[ config.ImageType[i] ], 0 );
- }
- }
- }
|