Skip to content

Commit 27ef05f

Browse files
authored
Merge pull request #147 from tsherif/simplify-xform-feedback
Simplify transform feedback sample
2 parents df6e5c8 + 2fa7898 commit 27ef05f

1 file changed

Lines changed: 88 additions & 194 deletions

File tree

samples/transform_feedback_separated_2.html

Lines changed: 88 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<p id="description">Using transform feedback in a simple particle system</p>
1919

2020
<!-- WebGL 2 shaders -->
21-
<script id="vs-emit" type="x-shader/x-vertex">
21+
<script id="vs-draw" type="x-shader/x-vertex">
2222
#version 300 es
2323
#define POSITION_LOCATION 0
2424
#define VELOCITY_LOCATION 1
@@ -62,49 +62,8 @@
6262
v_spawntime = a_spawntime;
6363
v_lifetime = a_lifetime;
6464
}
65-
}
66-
</script>
67-
68-
<!-- Unsused -->
69-
<script id="fs-emit" type="x-shader/x-fragment">
70-
#version 300 es
71-
precision highp float;
72-
precision highp int;
73-
74-
out vec4 color;
75-
76-
void main()
77-
{
78-
color = vec4(1.0);
79-
}
80-
</script>
81-
82-
<script id="vs-draw" type="x-shader/x-vertex">
83-
#version 300 es
84-
#define POSITION_LOCATION 0
85-
#define VELOCITY_LOCATION 1
86-
#define SPAWNTIME_LOCATION 2
87-
#define LIFETIME_LOCATION 3
88-
89-
precision highp float;
90-
precision highp int;
91-
92-
uniform float u_time;
93-
uniform vec2 u_acceleration;
94-
95-
layout(location = POSITION_LOCATION) in vec2 a_position;
96-
layout(location = VELOCITY_LOCATION) in vec2 a_velocity;
97-
layout(location = SPAWNTIME_LOCATION) in float a_spawntime;
98-
layout(location = LIFETIME_LOCATION) in float a_lifetime;
9965

100-
void main()
101-
{
102-
float deltaTime = u_time - a_spawntime;
103-
if (deltaTime < a_lifetime) {
104-
gl_Position = vec4(a_position, 0.0, 1.0);
105-
} else {
106-
gl_Position = vec4(-100.0, -100.0, 0.0, 1.0);
107-
}
66+
gl_Position = vec4(v_position, 0.0, 1.0);
10867
gl_PointSize = 2.0;
10968
}
11069
</script>
@@ -155,21 +114,12 @@
155114
var appStartTime = Date.now();
156115
var currentSourceIdx = 0;
157116

158-
// -- Init Program
159-
160-
var PROGRAM_EMIT = 0;
161-
var PROGRAM_DRAW = 1;
162-
163-
var programs = initPrograms();
164-
165-
// Get uniform locations for the transform feedback program
166-
var emitTimeLocation = gl.getUniformLocation(programs[PROGRAM_EMIT], 'u_time');
167-
var emitAccelerationLocation = gl.getUniformLocation(programs[PROGRAM_EMIT], 'u_acceleration');
117+
var program = initProgram();
168118

169119
// Get uniform locations for the draw program
170-
var drawTimeLocation = gl.getUniformLocation(programs[PROGRAM_DRAW], 'u_time');
171-
var drawAccelerationLocation = gl.getUniformLocation(programs[PROGRAM_DRAW], 'u_acceleration');
172-
var drawColorLocation = gl.getUniformLocation(programs[PROGRAM_DRAW], 'u_color');
120+
var drawTimeLocation = gl.getUniformLocation(program, 'u_time');
121+
var drawAccelerationLocation = gl.getUniformLocation(program, 'u_acceleration');
122+
var drawColorLocation = gl.getUniformLocation(program, 'u_color');
173123

174124
// -- Initialize particle data
175125

@@ -179,14 +129,12 @@
179129
var particleLifetime = new Float32Array(NUM_PARTICLES);
180130
var particleIDs = new Float32Array(NUM_PARTICLES);
181131

182-
var Particle = {
183-
POSITION: 0,
184-
VELOCITY: 1,
185-
SPAWN_TIME: 2,
186-
LIFE_TIME: 3,
187-
ID: 4,
188-
MAX: 5
189-
};
132+
var POSITION_LOCATION = 0;
133+
var VELOCITY_LOCATION = 1;
134+
var SPAWNTIME_LOCATION = 2;
135+
var LIFETIME_LOCATION = 3;
136+
var ID_LOCATION = 4;
137+
var NUM_LOCATIONS = 5;
190138

191139
for (var p = 0; p < NUM_PARTICLES; ++p) {
192140
particlePositions[p * 2] = 0.0;
@@ -198,207 +146,153 @@
198146
particleIDs[p] = p;
199147
}
200148

201-
// -- Init Buffer
149+
// -- Init Vertex Arrays and Buffers
150+
var particleVAOs = [gl.createVertexArray(), gl.createVertexArray()];
151+
152+
var particleVBOs = new Array(particleVAOs.length);
202153

203-
var particleVBOs = new Array(2);
154+
for (var i = 0; i < particleVAOs.length; ++i) {
155+
particleVBOs[i] = new Array(NUM_LOCATIONS);
204156

205-
for (var i = 0; i < 2; ++i) {
206-
particleVBOs[i] = new Array(Particle.MAX);
207-
for (var j = 0; j < Particle.MAX; ++j) {
208-
particleVBOs[i][j] = gl.createBuffer();
209-
}
157+
gl.bindVertexArray(particleVAOs[i]);
210158

211-
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][Particle.POSITION]);
159+
particleVBOs[i][POSITION_LOCATION] = gl.createBuffer();
160+
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][POSITION_LOCATION]);
212161
gl.bufferData(gl.ARRAY_BUFFER, particlePositions, gl.STREAM_COPY);
162+
gl.vertexAttribPointer(POSITION_LOCATION, 2, gl.FLOAT, false, 0, 0);
163+
gl.enableVertexAttribArray(POSITION_LOCATION);
213164

214-
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][Particle.VELOCITY]);
165+
particleVBOs[i][VELOCITY_LOCATION] = gl.createBuffer();
166+
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][VELOCITY_LOCATION]);
215167
gl.bufferData(gl.ARRAY_BUFFER, particleVelocities, gl.STREAM_COPY);
168+
gl.vertexAttribPointer(VELOCITY_LOCATION, 2, gl.FLOAT, false, 0, 0);
169+
gl.enableVertexAttribArray(VELOCITY_LOCATION);
216170

217-
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][Particle.SPAWN_TIME]);
171+
particleVBOs[i][SPAWNTIME_LOCATION] = gl.createBuffer();
172+
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][SPAWNTIME_LOCATION]);
218173
gl.bufferData(gl.ARRAY_BUFFER, particleSpawntime, gl.STREAM_COPY);
174+
gl.vertexAttribPointer(SPAWNTIME_LOCATION, 1, gl.FLOAT, false, 0, 0);
175+
gl.enableVertexAttribArray(SPAWNTIME_LOCATION);
219176

220-
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][Particle.LIFE_TIME]);
177+
particleVBOs[i][LIFETIME_LOCATION] = gl.createBuffer();
178+
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][LIFETIME_LOCATION]);
221179
gl.bufferData(gl.ARRAY_BUFFER, particleLifetime, gl.STREAM_COPY);
180+
gl.vertexAttribPointer(LIFETIME_LOCATION, 1, gl.FLOAT, false, 0, 0);
181+
gl.enableVertexAttribArray(LIFETIME_LOCATION);
222182

223-
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][Particle.ID]);
183+
particleVBOs[i][ID_LOCATION] = gl.createBuffer();
184+
gl.bindBuffer(gl.ARRAY_BUFFER, particleVBOs[i][ID_LOCATION]);
224185
gl.bufferData(gl.ARRAY_BUFFER, particleIDs, gl.STATIC_READ);
186+
gl.vertexAttribPointer(ID_LOCATION, 1, gl.FLOAT, false, 0, 0);
187+
gl.enableVertexAttribArray(ID_LOCATION);
225188
}
226189

227-
// -- Init Vertex Array
228-
var particleVAOs = [gl.createVertexArray(), gl.createVertexArray()];
229-
230-
var POSITION_LOCATION = 0;
231-
var VELOCITY_LOCATION = 1;
232-
var SPAWNTIME_LOCATION = 2;
233-
var LIFETIME_LOCATION = 3;
234-
var ID_LOCATION = 4;
235-
236-
// -- Init TransformFeedback
237-
var transformFeedback = gl.createTransformFeedback();
238-
239-
render();
190+
function initProgram() {
240191

241-
function initPrograms() {
242-
243-
// Setup program for transform feedback shaders
192+
// Setup program for transform feedback
244193
function createShader(gl, source, type) {
245194
var shader = gl.createShader(type);
246195
gl.shaderSource(shader, source);
247196
gl.compileShader(shader);
248197
return shader;
249198
}
250199

251-
var vshaderTransform = createShader(gl, getShaderSource('vs-emit'), gl.VERTEX_SHADER);
252-
var fshaderTransform = createShader(gl, getShaderSource('fs-emit'), gl.FRAGMENT_SHADER);
200+
var vshader = createShader(gl, getShaderSource('vs-draw'), gl.VERTEX_SHADER);
201+
var fshader = createShader(gl, getShaderSource('fs-draw'), gl.FRAGMENT_SHADER);
253202

254-
var programEmit = gl.createProgram();
255-
gl.attachShader(programEmit, vshaderTransform);
256-
gl.deleteShader(vshaderTransform);
257-
gl.attachShader(programEmit, fshaderTransform);
258-
gl.deleteShader(fshaderTransform);
203+
var program = gl.createProgram();
204+
gl.attachShader(program, vshader);
205+
gl.attachShader(program, fshader);
259206

260207
var varyings = ['v_position', 'v_velocity', 'v_spawntime', 'v_lifetime'];
261-
gl.transformFeedbackVaryings(programEmit, varyings, gl.SEPARATE_ATTRIBS);
262-
gl.linkProgram(programEmit);
208+
gl.transformFeedbackVaryings(program, varyings, gl.SEPARATE_ATTRIBS);
209+
gl.linkProgram(program);
263210

264211
// check
265-
var log = gl.getProgramInfoLog(programEmit);
212+
var log = gl.getProgramInfoLog(program);
266213
if (log) {
267214
console.log(log);
268215
}
269216

270-
log = gl.getShaderInfoLog(vshaderTransform);
217+
log = gl.getShaderInfoLog(vshader);
271218
if (log) {
272219
console.log(log);
273220
}
274221

275-
// Setup program for draw shader
276-
var programDraw = createProgram(gl, getShaderSource('vs-draw'), getShaderSource('fs-draw'));
277-
278-
var programs = [programEmit, programDraw];
279-
return programs;
280-
}
281-
282-
function setupVertexAttributes(vaoId, vboArray) {
283-
gl.bindVertexArray(vaoId);
284-
285-
gl.bindBuffer(gl.ARRAY_BUFFER, vboArray[Particle.POSITION]);
286-
gl.vertexAttribPointer(POSITION_LOCATION, 2, gl.FLOAT, false, 0, 0);
222+
log = gl.getShaderInfoLog(fshader);
223+
if (log) {
224+
console.log(log);
225+
}
287226

288-
gl.bindBuffer(gl.ARRAY_BUFFER, vboArray[Particle.VELOCITY]);
289-
gl.vertexAttribPointer(VELOCITY_LOCATION, 2, gl.FLOAT, false, 0, 0);
227+
gl.deleteShader(vshader);
228+
gl.deleteShader(fshader);
290229

291-
gl.bindBuffer(gl.ARRAY_BUFFER, vboArray[Particle.SPAWN_TIME]);
292-
gl.vertexAttribPointer(SPAWNTIME_LOCATION, 1, gl.FLOAT, false, 0, 0);
230+
return program;
231+
}
293232

294-
gl.bindBuffer(gl.ARRAY_BUFFER, vboArray[Particle.LIFE_TIME]);
295-
gl.vertexAttribPointer(LIFETIME_LOCATION, 1, gl.FLOAT, false, 0, 0);
233+
gl.useProgram(program);
234+
gl.uniform4f(drawColorLocation, 0.0, 1.0, 1.0, 1.0);
235+
gl.uniform2f(drawAccelerationLocation, 0.0, ACCELERATION);
236+
237+
gl.enable(gl.BLEND);
238+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
296239

297-
gl.bindBuffer(gl.ARRAY_BUFFER, vboArray[Particle.ID]);
298-
gl.vertexAttribPointer(ID_LOCATION, 1, gl.FLOAT, false, 0, 0);
240+
// -- Init TransformFeedback
241+
var transformFeedback = gl.createTransformFeedback();
242+
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
299243

300-
gl.enableVertexAttribArray(POSITION_LOCATION);
301-
gl.enableVertexAttribArray(VELOCITY_LOCATION);
302-
gl.enableVertexAttribArray(SPAWNTIME_LOCATION);
303-
gl.enableVertexAttribArray(LIFETIME_LOCATION);
304-
gl.enableVertexAttribArray(ID_LOCATION);
305-
}
244+
function render() {
306245

307-
function emitParticles() {
308246
var time = Date.now() - appStartTime;
309247

310-
var programEmit = programs[PROGRAM_EMIT];
248+
// Set the viewport
249+
gl.viewport(0, 0, canvas.width, canvas.height - 10);
250+
251+
// Clear color buffer
252+
gl.clearColor(0.0, 0.0, 0.0, 1.0);
253+
gl.clear(gl.COLOR_BUFFER_BIT);
311254

312255
// Toggle source and destination VBO
313-
var sourceVBO = particleVBOs[currentSourceIdx];
314256
var sourceVAO = particleVAOs[currentSourceIdx];
315-
316257
var destinationVBO = particleVBOs[(currentSourceIdx + 1) % 2];
317258

318-
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedback);
319-
320-
gl.useProgram(programEmit);
321-
322-
setupVertexAttributes(sourceVAO, sourceVBO);
259+
gl.bindVertexArray(sourceVAO);
323260

324261
// Set transform feedback buffer
325-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, destinationVBO[Particle.POSITION]);
326-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, destinationVBO[Particle.VELOCITY]);
327-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, destinationVBO[Particle.SPAWN_TIME]);
328-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, destinationVBO[Particle.LIFE_TIME]);
329-
330-
// Turn off rasterization - we are not drawing
331-
gl.enable(gl.RASTERIZER_DISCARD);
262+
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, destinationVBO[POSITION_LOCATION]);
263+
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, destinationVBO[VELOCITY_LOCATION]);
264+
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, destinationVBO[SPAWNTIME_LOCATION]);
265+
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, destinationVBO[LIFETIME_LOCATION]);
332266

333267
// Set uniforms
334-
gl.uniform1f(emitTimeLocation, time);
335-
gl.uniform2f(emitAccelerationLocation, 0.0, ACCELERATION);
268+
gl.uniform1f(drawTimeLocation, time);
336269

337-
// Emit particles using transform feedback
270+
// Draw particles using transform feedback
338271
gl.beginTransformFeedback(gl.POINTS);
339272
gl.drawArrays(gl.POINTS, 0, NUM_PARTICLES);
340273
gl.endTransformFeedback();
341274

342-
// Restore state
343-
gl.disable(gl.RASTERIZER_DISCARD);
344-
gl.useProgram(null);
345-
gl.bindBuffer(gl.ARRAY_BUFFER, null);
346-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
347-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null);
348-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, null);
349-
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 3, null);
350-
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
351-
352275
// Ping pong the buffers
353276
currentSourceIdx = (currentSourceIdx + 1) % 2;
354-
}
355-
356-
function render() {
357-
// Spawn particles
358-
emitParticles();
359-
360-
var time = Date.now() - appStartTime;
361-
362-
// Set the viewport
363-
gl.viewport(0, 0, canvas.width, canvas.height - 10);
364-
365-
// Clear color buffer
366-
gl.clearColor(0.0, 0.0, 0.0, 1.0);
367-
gl.clear(gl.COLOR_BUFFER_BIT);
368-
369-
setupVertexAttributes(particleVAOs[currentSourceIdx], particleVBOs[currentSourceIdx]);
370-
371-
gl.useProgram(programs[PROGRAM_DRAW]);
372-
373-
// Set uniforms
374-
gl.uniform1f(drawTimeLocation, time);
375-
gl.uniform4f(drawColorLocation, 0.0, 1.0, 1.0, 1.0);
376-
gl.uniform2f(drawAccelerationLocation, 0.0, ACCELERATION);
377-
378-
// Enable blending
379-
gl.enable(gl.BLEND);
380-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
381-
382-
gl.drawArrays(gl.POINTS, 0, NUM_PARTICLES);
383277

384278
requestAnimationFrame(render);
385279
}
386280

281+
requestAnimationFrame(render);
282+
387283
// If you have a long-running page, and need to delete WebGL resources, use:
388284
//
389285
// gl.deleteTransformFeedback(transformFeedback);
390-
// gl.deleteProgram(programs[PROGRAM_EMIT]);
391-
// gl.deleteProgram(programs[PROGRAM_DRAW]);
392-
// for (var i = 0; i < 2; ++i) {
393-
// for (var j = 0; j < Particle.MAX; ++j) {
286+
// gl.deleteProgram(program);
287+
// for (var i = 0; i < particleVAOs.length; ++i) {
288+
// gl.deleteVertexArray(i);
289+
// for (var j = 0; j < NUM_LOCATIONS; ++j) {
394290
// gl.deleteBuffer(particleVBOs[i][j]);
395291
// }
396292
// }
397-
// gl.deleteVertexArray(particleVAOs[PROGRAM_EMIT]);
398-
// gl.deleteVertexArray(particleVAOs[PROGRAM_DRAW]);
399293
})();
400294
</script>
401-
<div id="highlightedLines" style="display: none">#L318-L350</div>
295+
<div id="highlightedLines" style="display: none">#L246-L278</div>
402296

403297
</body>
404298

0 commit comments

Comments
 (0)