Example #1
0
    drawImplementation: function ( state ) {

        var program = state.getLastProgramApplied();
        var prgID = program.getInstanceID();

        var cachedDraw = this._cacheDrawCall[ prgID ];

        // most of the time we should use vao
        if ( this._extVAO && !this._vao[ prgID ] ) state.setVertexArrayObject( null );

        if ( cachedDraw === undefined ) {

            if ( !this._primitives.length ) return;

            // no cache for this combination of vertex attributes
            // compute new Draw Call

            if ( this._extVAO === undefined && Geometry.enableVAO ) { // will be null if not supported
                var extVAO = WebGLCaps.instance( state.getGraphicContext() ).getWebGLExtension( 'OES_vertex_array_object' );
                this._extVAO = extVAO;
            }

            cachedDraw = this.generateDrawCommand( state, program, prgID );
        }

        cachedDraw.call( this, state );

    },
Example #2
0
    test('WebGLCaps', function() {
        var canvas = mockup.createCanvas(true);
        var gl = canvas.getContext();
        var webglCaps = WebGLCaps.instance(gl);

        webglCaps.getWebGLExtensions().OES_texture_float = true; // eslint-disable-line
        webglCaps._checkRTT[Texture.FLOAT + ',' + Texture.NEAREST] = true;

        var hFloat = webglCaps.hasFloatRTT(gl);
        assert.isOk(hFloat, 'float detect');
    });
Example #3
0
    processShader: function(shader, defines, extensions, type) {
        // if the shader has #version statement we skip the shader processing
        if (this._hasVersion(shader)) {
            return shader;
        }

        var includeList = [];
        var preShader = shader;
        var sourceID = 0;
        if (this._debugLines) {
            preShader = this.instrumentShaderlines(preShader, sourceID);
            sourceID++;
        }

        // removes duplicates
        defines = this._getSortedUnique(defines);
        extensions = this._getSortedUnique(extensions);

        var strCore = this.preprocess(preShader, sourceID, includeList, defines, type);

        // avoid warning on unrecognized pragma
        strCore = strCore.replace(/#pragma DECLARE_FUNCTION/g, '//#pragma DECLARE_FUNCTION');

        var isFragment = strCore.indexOf('gl_Position') === -1;
        var convertToWebGL2 = WebglCaps.instance().isWebGL2();

        var strVersion = convertToWebGL2 ? '#version 300 es' : '#version 100';
        strVersion += '\n';

        var strExtensions = extensions ? extensions.join('\n') + '\n' : '';

        var strDefines = defines ? defines.join('\n') + '\n' : '';

        if (convertToWebGL2) {
            strExtensions = this._convertExtensionsToWebGL2(strExtensions);
            strDefines = this._convertToWebGL2(strDefines, isFragment);
            strCore = this._convertToWebGL2(strCore, isFragment);
        } else {
            // support multiline define
            strDefines = strDefines.replace(/\\\n/g, '');
            strCore = strCore.replace(/\\\n/g, '');
        }

        // vertex shader uses highp per default BUT if FS is using mediump then VS should too (conflict with varying/uniform otherwise)
        // also make sure precision is not already providen
        var strPrecision = '';
        if (this._globalDefaultprecision && !this._precisionR.test(strCore)) {
            strPrecision = this._globalDefaultprecision + '\n';
        }

        // order is important
        // See https://khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf (p14-15: extension before any non-processor token)
        return strVersion + strExtensions + strPrecision + strDefines + strCore;
    }
Example #4
0
            _getInternalFormatGL: function() {
                var internalFormat = this._internalFormat;

                // gl1
                if (!WebglCaps.instance().isWebGL2()) {
                    return internalFormatGl2ToGl1[internalFormat] || internalFormat;
                }

                // gl2
                var map = internalFormatGl1ToGl2[this._type];
                return (map && map[internalFormat]) || internalFormat;
            },
Example #5
0
        drawImplementation: function(state) {
            var program = state.getLastProgramApplied();
            var prgID = program.getInstanceID();

            state.drawGeometry(this);
            var cachedDraw = this._cacheDrawCall[prgID];

            if (!this._vao[prgID]) {
                state.setVertexArrayObject(null);
            } else {
                if (this._vao[prgID].isDirty()) {
                    // need vertex array recreation
                    // ie: lost context
                    cachedDraw = undefined;
                }
            }

            if (cachedDraw) {
                cachedDraw.call(this, state);
                return;
            }

            if (!this._primitives.length) {
                if (!this._warnNoPrimitives) {
                    notify.warn(
                        'geometry with instanceID ' + this._instanceID + ' has no primitives'
                    );
                    this._warnNoPrimitives = true;
                }
                return;
            }

            var validPrimitives = this._getValidPrimitives();
            if (!validPrimitives.length) return;

            // generate cachedDraw
            if (this._useVAO === undefined && Geometry.enableVAO) {
                // will be null if not supported
                this._useVAO = WebGLCaps.instance().hasVAO();
                this._glContext = state.getGraphicContext();
            }

            cachedDraw = this.generateDrawCommand(state, program, prgID, validPrimitives);
            cachedDraw.call(this, state);
            state.setVertexArrayObject(null);
        },
Example #6
0
    reset: function(gl) {
        if (gl) {
            var ext = WebGLCaps.instance(gl).getDisjointTimerQuery();
            if (!ext) return this;

            // webgl1 to webgl2
            if (!gl.getQueryParameter) gl.getQueryParameter = ext.getQueryObjectEXT.bind(ext);

            // https://github.com/KhronosGroup/WebGL/blob/master/sdk/tests/conformance/extensions/ext-disjoint-timer-query.html#L102
            // run the page if strange results
            // to validate you gpu/browser has correct gpu queries support
            this._hasTimeElapsed =
                gl.getQuery(ext.TIME_ELAPSED_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30;
            this._hasTimeStamp = gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30;

            if (!this._hasTimeElapsed && !this._hasTimeStamp) {
                return this;
            }

            // no timestamp means not start/end absolute time
            // which means each start must be followed by a end
            // BEFORE any other start (of other queryID)
            if (!this._hasTimeStamp) notify.debug('Warning: do not use interleaved GPU query');

            this._ext = ext;
            this._gl = gl;
            this._enabled = true;
        }

        this._frameAverageCount = 10;

        this._glQueries = [];
        this._queriesByID = {};
        this._userQueries = []; // for timestamp, it's the same as _glQueries

        // stuffs used to virtualize query (no timestamp)
        this._queryCount = 0;
        this._nbOpened = 0;
    },
Example #7
0
            setTextureSize: function(w, h) {
                var maxSize = WebglCaps.instance().getWebGLParameter('MAX_TEXTURE_SIZE');

                if (w !== this._textureWidth || h !== this._textureHeight) this.dirty();

                if (w !== undefined) {
                    if (w > maxSize) {
                        notify.error(
                            'width (' +
                                w +
                                ') too big for GPU. Max Texture Size is "' +
                                maxSize +
                                '"'
                        );
                        this._textureWidth = maxSize;
                    } else {
                        this._textureWidth = w;
                    }
                }

                if (h !== undefined) {
                    if (h > maxSize) {
                        notify.error(
                            'height (' +
                                h +
                                ') too big for GPU. Max Texture Size is "' +
                                maxSize +
                                '"'
                        );
                        this._textureHeight = maxSize;
                    } else {
                        this._textureHeight = h;
                    }
                }

                this._textureNull = false;
            },
Example #8
0
    test( 'FrameBufferObject', function () {

        var maxRenderBufferSize = WebglCaps.instance().getWebGLParameter( 'MAX_RENDERBUFFER_SIZE' );
        if ( maxRenderBufferSize === undefined ) {
            WebglCaps.instance().getWebGLParameters()[ 'MAX_RENDERBUFFER_SIZE' ] = 1;
            maxRenderBufferSize = 1;
        }

        ( function () {
            var gl = mockup.createFakeRenderer();
            var state = {
                getGraphicContext: function () {
                    return gl;
                },
                applyTextureAttribute: function () {}
            };


            var b = new FrameBufferObject();
            b.setAttachment( {
                texture: {
                    isDirty: function () {
                        return false;
                    },
                    getTextureObject: function () {
                        return {
                            id: function () {}
                        };
                    },
                    getWidth: function () {
                        return 1;
                    },
                    getHeight: function () {
                        return 1;
                    }
                },
                textureTarget: 'textureTarget'
            } );
            b.setAttachment( {
                format: 'texture',
                width: 1,
                height: 1
            } );

            b.dirty();
            b.apply( state );

            assert.isOk( b.getFrameBufferObject() !== undefined, 'Check we created gl framebuffer' );
            b.releaseGLObjects();
            assert.isOk( b.getFrameBufferObject() === undefined, 'Check we released gl famebuffer' );

            // check wrong frame buffer sizes
            b.setAttachment( {
                texture: {
                    isDirty: function () {
                        return false;
                    },
                    getTextureObject: function () {
                        return {
                            id: function () {}
                        };
                    },
                    getWidth: function () {
                        return maxRenderBufferSize + 1;
                    },
                    getHeight: function () {
                        return maxRenderBufferSize + 1;
                    }
                },
                textureTarget: 'textureTarget'
            } );
            b.setAttachment( {
                format: 'texture',
                width: maxRenderBufferSize + 1,
                height: maxRenderBufferSize + 1
            } );

            b.dirty();
            b.apply( state );
            assert.isOk( b.getFrameBufferObject() === undefined, 'Check we did not created gl framebuffer' );


        } )();

        ( function () {
            var gl = mockup.createFakeRenderer();
            var state = {
                getGraphicContext: function () {
                    return gl;
                },
                applyTextureAttribute: function () {}
            };


            var fbo = new FrameBufferObject();

            fbo.createFrameBufferObject( state );
            fbo.bindFrameBufferObject();
            var renderBuffer = fbo.createRenderBuffer( FrameBufferObject.DEPTH_COMPONENT16, 800, 600 );
            fbo.framebufferRenderBuffer( FrameBufferObject.DEPTH_ATTACHMENT, renderBuffer );

            var texture = new Texture();
            // mockup texture
            texture.getTextureObject = function () {
                return {
                    id: function () {
                        return 1;
                    }
                };
            };

            fbo.framebufferTexture2D( state, FrameBufferObject.COLOR_ATTACHMENT0, Texture.TEXTURE_2D, texture );

            fbo.apply( state );

            assert.isOk( fbo.isDirty() === false, 'Check that applied set dirty false even with no attachement' );
            assert.isOk( fbo.getFrameBufferObject() !== undefined, 'Check fbo' );

        } )();
    } );
Example #9
0
 _getTypeGL: function() {
     if (this._type === Texture.HALF_FLOAT && !WebglCaps.instance().isWebGL2())
         return Texture.HALF_FLOAT_OES;
     return this._type;
 }
Example #10
0
    initWebGLCaps: function ( gl ) {

        WebGLCaps.instance( gl );

    },