forked from playcanvas/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvertex-buffer.js
More file actions
175 lines (153 loc) · 5.51 KB
/
vertex-buffer.js
File metadata and controls
175 lines (153 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import { BUFFER_DYNAMIC, BUFFER_GPUDYNAMIC, BUFFER_STATIC, BUFFER_STREAM } from './constants.js';
let id = 0;
/**
* @class
* @name VertexBuffer
* @classdesc A vertex buffer is the mechanism via which the application specifies vertex
* data to the graphics hardware.
* @description Creates a new vertex buffer object.
* @param {GraphicsDevice} graphicsDevice - The graphics device used to manage this vertex buffer.
* @param {VertexFormat} format - The vertex format of this vertex buffer.
* @param {number} numVertices - The number of vertices that this vertex buffer will hold.
* @param {number} [usage] - The usage type of the vertex buffer (see BUFFER_*).
* @param {ArrayBuffer} [initialData] - Initial data.
*/
class VertexBuffer {
constructor(graphicsDevice, format, numVertices, usage = BUFFER_STATIC, initialData) {
// By default, vertex buffers are static (better for performance since buffer data can be cached in VRAM)
this.device = graphicsDevice;
this.format = format;
this.numVertices = numVertices;
this.usage = usage;
this.id = id++;
// vertex array object
this._vao = null;
// Calculate the size. If format contains verticesByteSize (non-interleaved format), use it
this.numBytes = format.verticesByteSize ? format.verticesByteSize : format.size * numVertices;
graphicsDevice._vram.vb += this.numBytes;
// Allocate the storage
if (initialData) {
this.setData(initialData);
} else {
this.storage = new ArrayBuffer(this.numBytes);
}
this.device.buffers.push(this);
}
/**
* @function
* @name VertexBuffer#destroy
* @description Frees resources associated with this vertex buffer.
*/
destroy() {
var device = this.device;
var idx = device.buffers.indexOf(this);
if (idx !== -1) {
device.buffers.splice(idx, 1);
}
if (this.bufferId) {
// clear up bound vertex buffers
var gl = device.gl;
device.boundVao = null;
gl.bindVertexArray(null);
// delete buffer
gl.deleteBuffer(this.bufferId);
device._vram.vb -= this.storage.byteLength;
this.bufferId = null;
}
}
// called when context was lost, function releases all context related resources
loseContext() {
this.bufferId = undefined;
this._vao = null;
}
/**
* @function
* @name VertexBuffer#getFormat
* @description Returns the data format of the specified vertex buffer.
* @returns {VertexFormat} The data format of the specified vertex buffer.
*/
getFormat() {
return this.format;
}
/**
* @function
* @name VertexBuffer#getUsage
* @description Returns the usage type of the specified vertex buffer. This indicates
* whether the buffer can be modified once and used many times {@link BUFFER_STATIC},
* modified repeatedly and used many times {@link BUFFER_DYNAMIC} or modified once
* and used at most a few times {@link BUFFER_STREAM}.
* @returns {number} The usage type of the vertex buffer (see BUFFER_*).
*/
getUsage() {
return this.usage;
}
/**
* @function
* @name VertexBuffer#getNumVertices
* @description Returns the number of vertices stored in the specified vertex buffer.
* @returns {number} The number of vertices stored in the vertex buffer.
*/
getNumVertices() {
return this.numVertices;
}
/**
* @function
* @name VertexBuffer#lock
* @description Returns a mapped memory block representing the content of the vertex buffer.
* @returns {ArrayBuffer} An array containing the byte data stored in the vertex buffer.
*/
lock() {
return this.storage;
}
/**
* @function
* @name VertexBuffer#unlock
* @description Notifies the graphics engine that the client side copy of the vertex buffer's
* memory can be returned to the control of the graphics driver.
*/
unlock() {
// Upload the new vertex data
var gl = this.device.gl;
if (!this.bufferId) {
this.bufferId = gl.createBuffer();
}
var glUsage;
switch (this.usage) {
case BUFFER_STATIC:
glUsage = gl.STATIC_DRAW;
break;
case BUFFER_DYNAMIC:
glUsage = gl.DYNAMIC_DRAW;
break;
case BUFFER_STREAM:
glUsage = gl.STREAM_DRAW;
break;
case BUFFER_GPUDYNAMIC:
if (this.device.webgl2) {
glUsage = gl.DYNAMIC_COPY;
} else {
glUsage = gl.STATIC_DRAW;
}
break;
}
gl.bindBuffer(gl.ARRAY_BUFFER, this.bufferId);
gl.bufferData(gl.ARRAY_BUFFER, this.storage, glUsage);
}
/**
* @function
* @name VertexBuffer#setData
* @description Copies data into vertex buffer's memory.
* @param {ArrayBuffer} [data] - Source data to copy.
* @returns {boolean} True if function finished successfuly, false otherwise.
*/
setData(data) {
if (data.byteLength !== this.numBytes) {
console.error("VertexBuffer: wrong initial data size: expected " + this.numBytes + ", got " + data.byteLength);
return false;
}
this.storage = data;
this.unlock();
return true;
}
}
export { VertexBuffer };