Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Sec3Engine/demos/ParticleDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,11 @@ function startDemo() {
SEC3ENGINE.run(gl);
}

function webGLStart() {
function webGLStart() {

canvas = document.getElementById("glcanvas");
initGL(canvas);
canvas = document.getElementById("glcanvas");
SEC3.canvas = canvas;
initGL(canvas);

camera = SEC3ENGINE.createCamera(CAMERA_TRACKING_TYPE);
camera.goHome([0.0, 0.0, 10.0]);
Expand Down
13 changes: 13 additions & 0 deletions Sec3Engine/demos/SEC3DEMO.js
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,19 @@ var setupScene = function(canvasId, messageId ) {
console.log("Bad GL Context!");
return;
}

// The renderer relies on multiple render targets, which require the
// WEBGL_draw_buffers extension in WebGL 1. Prefer to fail fast when the
// extension is unavailable (for example, when the browser has reduced GPU
// support enabled) rather than letting the pipeline fail later with vague
// WebGL errors.
if (!gl.getExtension("WEBGL_draw_buffers")) {
console.warn("WEBGL_draw_buffers extension unavailable; rendering will fail.");
if (msg) {
msg.innerText = "WEBGL_draw_buffers is required for SEC3DEMO.";
}
return;
Comment on lines +522 to +527

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Abort init when draw_buffers extension missing

The new WEBGL_draw_buffers guard in setupScene returns early when the extension is disabled, but main continues to call setKeyInputs, SEC3.renderer.init(), etc. without checking that initialization succeeded. In environments without the extension (the case this code targets), scene, interactor, and related globals are never created, so downstream calls will throw (e.g., interactor.onKeyDown in setKeyInputs) instead of failing fast. Consider surfacing the failure to main or skipping the rest of initialization when the extension check fails.

Useful? React with 👍 / 👎.

}

gl.viewport( 0, 0, canvas.width, canvas.height );
gl.viewportWidth = canvas.width;
Expand Down
123 changes: 88 additions & 35 deletions Sec3Engine/js/core/ParticleSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,39 @@ SEC3.createParticleSystem = function(specs) {

var renderProgram;
var stepProgram;
var interactor = {};
interactor.attractor = [ -13.0, 6.0, 1.0, 1.0 ];
var self = {};
var interactor = {};
interactor.attractor = [ -13.0, 6.0, 1.0, 1.0 ];
var self = {};

// Helpers to safely access optional scene and camera globals used by legacy demos.
var getActiveCamera = function() {
if (typeof scene !== "undefined" && scene.getCamera) {
return scene.getCamera();
}
if (typeof camera !== "undefined") {
return camera;
}
return null;
};

var getActiveLight = function() {
if (typeof scene !== "undefined" && scene.getLight && scene.getNumLights && scene.getNumLights() > 0) {
return scene.getLight(0);
}
return null;
};

//----------------------------------------------------------------METHODS:


var update = function() {
var update = function() {

stepParticles();
updateShadowMap(scene.getLight(0));
};
stepParticles();
var activeLight = getActiveLight();
if (activeLight) {
updateShadowMap(activeLight);
}
};

var draw = function( light ) {
renderParticles( light );
Expand Down Expand Up @@ -96,21 +117,28 @@ SEC3.createParticleSystem = function(specs) {

gl.vertexAttribPointer(stepProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(stepProgram.aVertexPosition);
var center = vec3.clone(scene.getCamera().getPosition());
var offset = vec3.clone(camera.normal);
vec3.scale(offset, offset, -6.0);
vec3.add(center, center, offset);
gl.uniform4f(stepProgram.uAttractor, center[0], center[1], center[2], 0.4 );
var activeCamera = getActiveCamera();
if (activeCamera) {
var center = vec3.clone(activeCamera.getPosition());
var offset = vec3.clone(activeCamera.normal);
vec3.scale(offset, offset, -6.0);
vec3.add(center, center, offset);
gl.uniform4f(stepProgram.uAttractor, center[0], center[1], center[2], 0.4 );
}

gl.drawArrays(gl.TRIANGLES, 0, 6);
}

/*
* draws current scene into shadow map
*/
var updateShadowMap = function ( light ) {
var updateShadowMap = function ( light ) {

if (!light || !light.cascadeFramebuffers || !light.cascadeFramebuffers[0]) {
return;
}

var fbo = light.cascadeFramebuffers[0];
var fbo = light.cascadeFramebuffers[0];
gl.colorMask(false,false,false,false);
gl.useProgram(self.shadowProgram.ref());
gl.viewport(0, 0, fbo.getWidth(), fbo.getHeight());
Expand Down Expand Up @@ -139,30 +167,49 @@ SEC3.createParticleSystem = function(specs) {
/*
* Draws all particles in system
*/
var renderParticles = function ( light ) {
var renderParticles = function ( light ) {

light = light || getActiveLight();
if (!light || !light.cascadeFramebuffers || !light.cascadeFramebuffers[0]) {
return;
}

gl.useProgram(self.renderProgram.ref());
gl.viewport(0, 0, SEC3.canvas.width, SEC3.canvas.height );


gl.uniform3fv(renderProgram.uLightPosition, light.getPosition());
gl.uniform3fv(renderProgram.uCPosLoc, scene.getCamera().getPosition());

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, positionTextures[srcIndex]);
gl.uniform1i( renderProgram.uParticlePositions, 0);

gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, SEC3.gBuffer.depthTexture() );
gl.uniform1i( renderProgram.uGDepthLoc, 1 );

gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, light.cascadeFramebuffers[0].depthTexture() );
gl.uniform1i(renderProgram.uShadowMap, 2);

gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, light.getMVP() );
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, scene.getCamera().getMVP());
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition() );
if (light) {
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition());
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniform3fv(renderProgram.uCPosLoc, activeCamera.getPosition());
}

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, positionTextures[srcIndex]);
gl.uniform1i( renderProgram.uParticlePositions, 0);

if (SEC3.gBuffer && SEC3.gBuffer.depthTexture) {
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, SEC3.gBuffer.depthTexture() );
gl.uniform1i( renderProgram.uGDepthLoc, 1 );
}

if (light) {
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, light.cascadeFramebuffers[0].depthTexture() );
gl.uniform1i(renderProgram.uShadowMap, 2);

gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, light.getMVP() );
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, activeCamera.getMVP());
}
if (light) {
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition() );
}
//bind the default frame buffer, disable depth testing and enable alpha blending
finalFBO.bind(gl);

Expand Down Expand Up @@ -293,8 +340,14 @@ SEC3.createParticleSystem = function(specs) {
renderProgram.uShadowMultiply = gl.getUniformLocation(renderProgram.ref(), "uShadowMultiply");
renderProgram.uScale = gl.getUniformLocation(renderProgram.ref(), "uScale");
gl.useProgram(renderProgram.ref());
gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, scene.getLight(0).getMVP());
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, scene.getCamera().getMVP());
var activeLight = getActiveLight();
if (activeLight) {
gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, activeLight.getMVP());
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, activeCamera.getMVP());
}
gl.uniform2fv( renderProgram.uScreenSizeLoc, vec2.fromValues(SEC3.canvas.width, SEC3.canvas.height ));
gl.uniform1f(renderProgram.uLuminence, self.luminence);
gl.uniform1f(renderProgram.uAlpha, self.RGBA[3]);
Expand Down
16 changes: 13 additions & 3 deletions Sec3Engine/js/core/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@
//SEC3 is a core function interface
var SEC3 = SEC3 || {};

// Camera type constants expected by legacy demos.
var CAMERA_EXPLORING_TYPE = 0;
var CAMERA_TRACKING_TYPE = 1;

SEC3.Camera = function(){

SEC3.PerspProjector.call( this );

};

SEC3.Camera.prototype = Object.create( SEC3.PerspProjector.prototype );

SEC3.Camera.prototype = Object.create( SEC3.PerspProjector.prototype );

// Convenience factory used by demo pages.
SEC3.createCamera = function(/* type */){
// Only one camera type is implemented; ignore the requested type for now.
return new SEC3.Camera();
};
18 changes: 15 additions & 3 deletions Sec3Engine/js/core/shader-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,22 @@ SEC3.createShaderProgram = function(){
var program = null; //shader program
var callbackFunArray = [];

function loadShaderFile( gl, fileName, shader, prefix ){
function loadShaderFile( gl, fileName, shader, prefix ){
var drawBuffersExt = gl.getExtension("WEBGL_draw_buffers");
prefix = prefix || "";
prefix = "#extension GL_EXT_draw_buffers: enable\nprecision highp float; \n" + prefix;
var request = new XMLHttpRequest();
var basePrefix = "precision highp float; \n";

if (drawBuffersExt) {
// Only ask GLSL to enable the extension when it is available; some
// browsers (notably mobile Safari) disable it when GPU capability is
// reduced, and requesting it regardless can cause vague shader link
// failures instead of falling back to the supported feature set.
prefix = "#extension GL_EXT_draw_buffers: enable\n" + basePrefix + prefix;
} else {
prefix = basePrefix + prefix;
}

var request = new XMLHttpRequest();

//Register a callback function
//
Expand Down
24 changes: 17 additions & 7 deletions particleDemo.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@
<title>Sec3 Particle Demo</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<!-- glMatrix version 2.2.0 -->
<script type="text/javascript" src="/Sec3Engine/js/math/gl-matrix.js"></script>
<script src="Sec3Engine/js/core/ParticleSystem.js" type="text/javascript"></script>
<script type="text/javascript" src="/Sec3Engine/js/math/gl-matrix.js"></script>
<script src="Sec3Engine/js/core/SceneObject.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/projector.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/PerspProjector.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/ParticleSystem.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/shader-util.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/webgl-util.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/camera.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/cameraInteractor.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/particleInteractor.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/texture.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/extensions.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/geometry.js" type ="text/javascript"></script>
<script src="/Sec3Engine/js/math/UI.js" type="text/javascript"></script>
<script src="/Sec3Engine/js/math/math.js" type="text/javascript"></script>
<script src="ParticleSystem/ParticleDemo.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/extensions.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/geometry.js" type ="text/javascript"></script>
<script src="/Sec3Engine/js/math/UI.js" type="text/javascript"></script>
<script src="/Sec3Engine/js/math/math.js" type="text/javascript"></script>
<script type="text/javascript">
// Legacy demos expect the engine API under the SEC3ENGINE name.
// Merge any helpers attached to the old namespace (for example
// ParticleInteractor) and expose the combined API under both names.
SEC3ENGINE = Object.assign(SEC3, SEC3ENGINE || {});
SEC3 = SEC3ENGINE;
</script>
<script src="Sec3Engine/demos/ParticleDemo.js" type="text/javascript"></script>

</head>

Expand Down