Newer
Older
pixi.js / src / mesh / webgl / MeshRenderer.js
@Mat Groves Mat Groves on 15 Nov 2016 5 KB pass one of geom
import * as core from '../../core';
import glCore from 'pixi-gl-core';
import { default as Mesh } from '../Mesh';

/**
 * WebGL renderer plugin for tiling sprites
 */
export default class MeshRenderer extends core.ObjectRenderer {

    /**
     * constructor for renderer
     *
     * @param {WebGLRenderer} renderer The renderer this tiling awesomeness works for.
     */
    constructor(renderer)
    {
        super(renderer);

        this.shader = null;
    }

    /**
     * Sets up the renderer context and necessary buffers.
     *
     * @private
     */
    onContextChange()
    {
        this.gl = this.renderer.gl;

        //nothing to see here!
    }

    /**
     * renders mesh
     *
     * @param {PIXI.mesh.Mesh} mesh mesh instance
     */
    render(mesh)
    {
        // get rid of any thing that may be batching.
//        renderer.flush();

        // always use shaders - rather than GLShadr

        // generate geometry structure from a shader :)

        // set the shader props..
        if (mesh.shader.uniforms.translationMatrix)
        {
            // the transform!
            mesh.shader.uniforms.translationMatrix = mesh.transform.worldTransform.toArray(true);
        }

          // set the correct blend mode
        renderer.state.setBlendMode(mesh.blendMode);

        // bind the shader..
        // TODO rename filter to shader
        renderer.bindShader(mesh.shader);

        // now time for geometry..

        // bind the geometry...
        this.bindGeometry(mesh.geometry);

        // then render it..
        this.renderGeometry(mesh.geometry, mesh.drawMode);

        // then unbind it..
        // TODO - maybe create a state in renderer for geometry?
        // maybe renderer shouldxwww be a renderer?
        // although pretty much ALL items will simply be geometry + shader
        // TODO wont be required!
//        this.unbindGeometry(mesh.geometry);

    }

    bindGeometry(geometry)
    {
        const vao = geometry.glVertexArrayObjects[this.CONTEXT_UID] || this.initGeometryVao(geometry);

        this.renderer.bindVao(vao);

        if (geometry.autoUpdate)
        {
            // TODO - optimise later!
            for (let i = 0; i < geometry.buffers.length; i++)
            {
                const buffer = geometry.buffers[i];

                const glBuffer = buffer._glBuffers[this.CONTEXT_UID];

                if (buffer._updateID !== glBuffer._updateID)
                {
                    glBuffer._updateID = buffer._updateID;

                    // TODO - partial upload??
                    glBuffer.upload(buffer.data, 0);
                }
            }
        }
    }

    unbindGeometry(geometry)
    {
        const vao = geometry.glVertexArrayObjects[this.CONTEXT_UID];
        vao.unbind();
    }

    renderGeometry(geometry, drawMode)
    {
        const gl = this.gl;

        const vao = geometry.glVertexArrayObjects[this.CONTEXT_UID];

        // TODO - build a map
/*        if (drawMode === CONST.DRAW_MODES.TRIANGLE_MESH)
        {
<<<<<<< 79177787e99a4893e30f81fc1672bf6ccc026c1e
            glData.dirty = mesh.dirty;
            glData.uvBuffer.upload(mesh.uvs);
=======
            drawMode = gl.POINTS;
>>>>>>> pass one of geom
        }
        else if (drawMode === CONST.DRAW_MODES.POINTS)
        {
            drawMode = gl.POINTS;
        }
        else
        {
            drawMode = gl.POINTS;
        }*/

        drawMode = gl.TRIANGLES;

        vao.draw(drawMode);
    }

    initGeometryVao(geometry)
    {
        const gl = this.gl;

        const vao = this.renderer.createVao();

        const buffers = geometry.data.buffers;

        // first update - and creat the buffers!
        for (let i = 0; i < buffers.length; i++)
        {
            const buffer = buffers[i];

            if (!buffer._glBuffers[this.CONTEXT_UID])
            {
                if (buffer.index)
                {
                    buffer._glBuffers[this.CONTEXT_UID] = glCore.GLBuffer.createIndexBuffer(gl, buffer.data);
                }
                else
                {
                    buffer._glBuffers[this.CONTEXT_UID] = glCore.GLBuffer.createVertexBuffer(gl, buffer.data);
                }
            }
        }

        // first update the index buffer..
        vao.addIndex(geometry.data.indexBuffer._glBuffers[this.CONTEXT_UID]);

        const map = geometry.style.generateAttributeLocations();

        // next update the attributes buffer..
        for (const j in geometry.style.attributes)
        {
            const attribute = geometry.style.attributes[j];
            const buffer = geometry.data[attribute.buffer];

            // need to know the shader..
            // or DO we... NOPE!
            const glBuffer = buffer._glBuffers[this.CONTEXT_UID];

            vao.addAttribute(glBuffer, {
                size: attribute.size,
                location: map[j],
            }, gl.FLOAT, false, attribute.stride, attribute.start);
        }

        geometry.glVertexArrayObjects[this.CONTEXT_UID] = vao;

        return vao;
    }
}

core.WebGLRenderer.registerPlugin('mesh', MeshRenderer);