UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

131 lines (113 loc) 5.37 kB
/** * @author Benjamin D. Richards <benjamindrichards@gmail.com> * @copyright 2013-2026 Phaser Studio Inc. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var Class = require('../../../utils/Class'); /** * @classdesc * Wraps a WebGL vertex buffer together with its attribute layout description. * This class manages the relationship between a `WebGLBufferWrapper` (the raw * GPU buffer) and the attribute layout that describes how vertex data is * arranged within it, including the stride, per-attribute byte counts, and * byte offsets. It is used by Phaser's WebGL renderer to bind vertex data to * shader attribute locations when drawing geometry. On construction, the * layout is completed by computing stride, byte counts, and offsets from the * provided attribute definitions, and any GL enum values specified as strings * are resolved to their numeric equivalents. * * @class WebGLVertexBufferLayoutWrapper * @memberof Phaser.Renderer.WebGL.Wrappers * @constructor * @since 4.0.0 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGLRenderer instance that owns this wrapper. * @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The program that this layout is associated with. * @param {Partial<Phaser.Types.Renderer.WebGL.WebGLAttributeBufferLayout>} layout - The layout of the buffer. At construction, this should be incomplete. The stride and per-attribute location, bytes, and offset will be filled in during construction. This will mutate the object. * @param {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} [buffer] - The buffer that this layout should use. If not provided, a new buffer will be created. If the buffer is too small, an exception is thrown. * @throws {Error} If the buffer is too small for the layout. */ var WebGLVertexBufferLayoutWrapper = new Class({ initialize: function WebGLVertexBufferLayoutWrapper (renderer, layout, buffer) { /** * The WebGLRenderer instance that owns this wrapper. * * @name Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#renderer * @type {Phaser.Renderer.WebGL.WebGLRenderer} * @since 4.0.0 */ this.renderer = renderer; /** * The completed attribute buffer layout, describing the stride, * attributes, their types, sizes, byte counts, and byte offsets * within the vertex buffer. * * @name Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#layout * @type {Phaser.Types.Renderer.WebGL.WebGLAttributeBufferLayout} * @since 4.0.0 */ this.layout = layout; // Fill in the layout with the stride // and per-attribute bytes and offset. this.completeLayout(layout); var bufferSize = layout.stride * layout.count; if (buffer && buffer.byteLength < bufferSize) { throw new Error('Buffer too small for layout'); } /** * The WebGLBufferWrapper holding the vertex data for this layout. * * @name Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#buffer * @type {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} * @since 4.0.0 */ this.buffer = buffer || renderer.createVertexBuffer(new ArrayBuffer(bufferSize), layout.usage); }, /** * Complete the layout of the provided attribute buffer layout. * This will fill in the stride, byte counts, and offsets. * In addition, it will convert any GLenums specified as strings * to their numeric values. * This mutates the layout. * * The order of attributes within the layout forms the order of the buffer. * * @method Phaser.Renderer.WebGL.Wrappers.WebGLVertexBufferLayoutWrapper#completeLayout * @since 4.0.0 * @param {Phaser.Types.Renderer.WebGL.WebGLAttributeBufferLayout} attributeBufferLayout - The layout to complete. */ completeLayout: function (attributeBufferLayout) { var gl = this.renderer.gl; var layout = attributeBufferLayout.layout; var constants = this.renderer.shaderSetters.constants; if (typeof attributeBufferLayout.usage === 'string') { attributeBufferLayout.usage = gl[attributeBufferLayout.usage]; } var offset = 0; for (var i = 0; i < layout.length; i++) { var attribute = layout[i]; var size = attribute.size; var columns = attribute.columns || 1; // First, append the current offset. attribute.offset = offset; // Convert the type to a GLenum if it is a string. if (typeof attribute.type === 'string') { attribute.type = gl[attribute.type]; } var typeData = constants[attribute.type]; var baseSize = typeData.size; var baseBytes = typeData.bytes; // Append the bytes per attribute element. attribute.bytes = baseBytes; offset += size * columns * baseBytes * baseSize; } // Now that we know the total stride, we can set it. attributeBufferLayout.stride = offset; } }); module.exports = WebGLVertexBufferLayoutWrapper;