jax 0.0.0.8 → 0.0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +22 -0
- data/Rakefile +2 -1
- data/builtin/shaders/functions/noise.ejs +0 -3
- data/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js +31 -3
- data/guides/jax_guides/common.rb +1 -1
- data/guides/source/index.html.erb +4 -4
- data/guides/source/shaders.textile +496 -2
- data/lib/jax/generators/app/templates/public/javascripts/jax.js +130 -94
- data/lib/jax/generators/app/templates/spec/javascripts/support/spec_helpers/jax_spec_environment_helper.js +33 -0
- data/lib/jax/generators/app/templates/spec/javascripts/support/spec_layout.html.erb +1 -13
- data/lib/jax/generators/shader/templates/fragment.ejs.tt +2 -3
- data/lib/jax/generators/shader/templates/spec.js.tt +4 -11
- data/lib/jax/routes.rb +0 -3
- data/lib/jax/tasks/rake.rb +4 -0
- data/lib/jax/version.rb +1 -1
- data/spec/example_app/app/shaders/blob/vertex.ejs +2 -0
- data/spec/example_app/spec/javascripts/shaders/blob_spec.js +5 -8
- data/spec/example_app/spec/javascripts/support/spec_helpers/jax_spec_environment_helper.js +33 -0
- data/spec/example_app/spec/javascripts/support/spec_layout.html.erb +1 -13
- data/spec/generators/app_generator_spec.rb +1 -0
- data/spec/javascripts/helpers/jax_spec_environment_helper.js +33 -0
- data/spec/javascripts/helpers/{SpecHelper.js → jax_spec_helper.js} +0 -0
- data/spec/javascripts/jax/core/utils_spec.js +21 -2
- data/spec/lib/jax/tasks/jax_rake_spec.rb +13 -0
- data/src/jax/context.js +1 -1
- data/src/jax/core/util.js +12 -5
- data/src/jax/mvc/model.js +1 -0
- data/src/jax/webgl/scene/light_manager.js +58 -45
- data/src/jax/webgl/scene/light_source.js +49 -4
- data/src/jax/webgl/world.js +12 -46
- metadata +11 -6
data/lib/jax/routes.rb
CHANGED
@@ -30,9 +30,6 @@ module Jax
|
|
30
30
|
|
31
31
|
outfile.puts "Jax.routes.map(#{path.inspect}, #{controller_name_for(set[1])}, #{args});"
|
32
32
|
end
|
33
|
-
|
34
|
-
outfile.puts "if (Jax.doVersionCheck) Jax.doVersionCheck('#{Jax::Version::STRING}');"
|
35
|
-
outfile.puts "else alert('Your Jax gem version is newer than your Jax JavaScript library!\\n\\nRun `rake jax:update` to fix this.');"
|
36
33
|
end
|
37
34
|
|
38
35
|
def root(controller = nil, action = 'index')
|
data/lib/jax/tasks/rake.rb
CHANGED
@@ -27,6 +27,10 @@ namespace :jax do
|
|
27
27
|
File.open(Jax.root.join("tmp/routes.js"), 'w') do |f|
|
28
28
|
Jax.application.config.routes.compile(f)
|
29
29
|
end
|
30
|
+
File.open(Jax.root.join("tmp/version_check.js"), "w") do |f|
|
31
|
+
f.puts "if (Jax.doVersionCheck) Jax.doVersionCheck('#{Jax::Version::STRING}');"
|
32
|
+
f.puts "else alert('Your Jax gem version is newer than your Jax JavaScript library!\\n\\nRun `rake jax:update` to fix this.');"
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
data/lib/jax/version.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
describe("Shader 'blob'", function() {
|
2
|
-
var
|
2
|
+
var material, mesh;
|
3
3
|
|
4
4
|
beforeEach(function() {
|
5
|
-
context = new Jax.Context('webgl-canvas');
|
6
5
|
mesh = new Jax.Mesh.Quad();
|
7
6
|
});
|
8
7
|
|
9
|
-
afterEach(function() { context.dispose(); });
|
10
|
-
|
11
8
|
describe("stand-alone", function() {
|
12
9
|
beforeEach(function() { mesh.material = new Jax.Material.Blob(); });
|
13
10
|
|
14
|
-
|
15
|
-
expect(function() { mesh.render(
|
11
|
+
it("should render without error", function() {
|
12
|
+
expect(function() { mesh.render(SPEC_CONTEXT); }).not.toThrow();
|
16
13
|
});
|
17
14
|
});
|
18
15
|
|
@@ -23,8 +20,8 @@ describe("Shader 'blob'", function() {
|
|
23
20
|
}]});
|
24
21
|
});
|
25
22
|
|
26
|
-
|
27
|
-
expect(function() { mesh.render(
|
23
|
+
it("should render without error", function() {
|
24
|
+
expect(function() { mesh.render(SPEC_CONTEXT); }).not.toThrow();
|
28
25
|
});
|
29
26
|
});
|
30
27
|
});
|
@@ -0,0 +1,33 @@
|
|
1
|
+
function setupJaxTestEnvironment() {
|
2
|
+
var jasmineEnv = jasmine.getEnv();
|
3
|
+
|
4
|
+
jsApiReporter = new jasmine.JsApiReporter();
|
5
|
+
var trivialReporter = new jasmine.TrivialReporter();
|
6
|
+
|
7
|
+
jasmineEnv.addReporter(jsApiReporter);
|
8
|
+
jasmineEnv.addReporter(trivialReporter);
|
9
|
+
|
10
|
+
jasmineEnv.specFilter = function(spec) {
|
11
|
+
return trivialReporter.specFilter(spec);
|
12
|
+
};
|
13
|
+
|
14
|
+
/*
|
15
|
+
Create a canvas element and add it to the document.
|
16
|
+
There's nothing special about this element.
|
17
|
+
*/
|
18
|
+
var canvas = document.createElement("canvas");
|
19
|
+
canvas.setAttribute("id", "spec-canvas");
|
20
|
+
canvas.style.display = "none";
|
21
|
+
document.body.appendChild(canvas);
|
22
|
+
|
23
|
+
beforeEach(function() {
|
24
|
+
window.SPEC_CONTEXT = new Jax.Context(canvas);
|
25
|
+
});
|
26
|
+
|
27
|
+
afterEach(function() {
|
28
|
+
SPEC_CONTEXT.dispose();
|
29
|
+
})
|
30
|
+
|
31
|
+
|
32
|
+
jasmineEnv.execute();
|
33
|
+
}
|
@@ -14,20 +14,8 @@
|
|
14
14
|
<script type="text/javascript">
|
15
15
|
var jsApiReporter;
|
16
16
|
(function() {
|
17
|
-
var jasmineEnv = jasmine.getEnv();
|
18
|
-
|
19
|
-
jsApiReporter = new jasmine.JsApiReporter();
|
20
|
-
var trivialReporter = new jasmine.TrivialReporter();
|
21
|
-
|
22
|
-
jasmineEnv.addReporter(jsApiReporter);
|
23
|
-
jasmineEnv.addReporter(trivialReporter);
|
24
|
-
|
25
|
-
jasmineEnv.specFilter = function(spec) {
|
26
|
-
return trivialReporter.specFilter(spec);
|
27
|
-
};
|
28
|
-
|
29
17
|
window.onload = function() {
|
30
|
-
|
18
|
+
setupJaxTestEnvironment();
|
31
19
|
|
32
20
|
/*
|
33
21
|
Create a canvas element and add it to the document.
|
@@ -15,6 +15,7 @@ EXPECTED_FILES = %w(
|
|
15
15
|
spec/javascripts/support/jasmine.yml
|
16
16
|
spec/javascripts/support/jasmine_runner.rb
|
17
17
|
spec/javascripts/support/spec_layout.html.erb
|
18
|
+
spec/javascripts/support/spec_helpers/jax_spec_environment_helper.js
|
18
19
|
spec/javascripts/support/spec_helpers/jax_spec_helper.js
|
19
20
|
Rakefile
|
20
21
|
Gemfile
|
@@ -0,0 +1,33 @@
|
|
1
|
+
function setupJaxTestEnvironment() {
|
2
|
+
var jasmineEnv = jasmine.getEnv();
|
3
|
+
|
4
|
+
jsApiReporter = new jasmine.JsApiReporter();
|
5
|
+
var trivialReporter = new jasmine.TrivialReporter();
|
6
|
+
|
7
|
+
jasmineEnv.addReporter(jsApiReporter);
|
8
|
+
jasmineEnv.addReporter(trivialReporter);
|
9
|
+
|
10
|
+
jasmineEnv.specFilter = function(spec) {
|
11
|
+
return trivialReporter.specFilter(spec);
|
12
|
+
};
|
13
|
+
|
14
|
+
/*
|
15
|
+
Create a canvas element and add it to the document.
|
16
|
+
There's nothing special about this element.
|
17
|
+
*/
|
18
|
+
var canvas = document.createElement("canvas");
|
19
|
+
canvas.setAttribute("id", "spec-canvas");
|
20
|
+
canvas.style.display = "none";
|
21
|
+
document.body.appendChild(canvas);
|
22
|
+
|
23
|
+
beforeEach(function() {
|
24
|
+
window.SPEC_CONTEXT = new Jax.Context(canvas);
|
25
|
+
});
|
26
|
+
|
27
|
+
afterEach(function() {
|
28
|
+
SPEC_CONTEXT.dispose();
|
29
|
+
})
|
30
|
+
|
31
|
+
|
32
|
+
jasmineEnv.execute();
|
33
|
+
}
|
File without changes
|
@@ -2,6 +2,19 @@ describe("Jax.Util", function() {
|
|
2
2
|
describe("vectorize", function() {
|
3
3
|
var data;
|
4
4
|
|
5
|
+
describe("2D", function() {
|
6
|
+
beforeEach(function() { data = [1, 2]; });
|
7
|
+
|
8
|
+
it("should have length 2", function() { expect(Jax.Util.vectorize({x:0,y:1})).toEqualVector([0,1]); });
|
9
|
+
it("should work", function() { expect(Jax.Util.vectorize(data)).toEqualVector([1,2]); });
|
10
|
+
});
|
11
|
+
|
12
|
+
describe("with array", function() {
|
13
|
+
beforeEach(function() { data = [1, 2, 3]; });
|
14
|
+
|
15
|
+
it("should return the original vector", function() { expect(Jax.Util.vectorize(data)).toEqualVector([1,2,3]); });
|
16
|
+
});
|
17
|
+
|
5
18
|
describe("with object with names", function() {
|
6
19
|
beforeEach(function() { data = {x:1,y:2,z:3}; });
|
7
20
|
it("should produce a vector", function() { expect(Jax.Util.vectorize(data)).toEqualVector([1,2,3]); });
|
@@ -33,6 +46,12 @@ describe("Jax.Util", function() {
|
|
33
46
|
describe("colorize", function() {
|
34
47
|
var data;
|
35
48
|
|
49
|
+
describe("3D", function() {
|
50
|
+
beforeEach(function() { data = [1, 2, 3]; });
|
51
|
+
|
52
|
+
it("should work", function() { expect(Jax.Util.colorize(data)).toEqualVector([1,2,3,1]); });
|
53
|
+
});
|
54
|
+
|
36
55
|
describe("with object with short names", function() {
|
37
56
|
beforeEach(function() { data = {r:1,g:2,b:3,a:4}; });
|
38
57
|
it("should produce a color", function() { expect(Jax.Util.colorize(data)).toEqualVector([1,2,3,4]); });
|
@@ -108,7 +127,7 @@ describe("Jax.Util", function() {
|
|
108
127
|
describe("with a vector", function() {
|
109
128
|
beforeEach(function() { data = [1,2,3]; });
|
110
129
|
it("should produce a vector", function() { expect(Jax.Util.vectorize(data)).toEqualVector([1,2,3]); });
|
111
|
-
|
130
|
+
xit("should not return itself", function() { expect(Jax.Util.vectorize(data)).not.toEqual(data); });
|
112
131
|
});
|
113
132
|
});
|
114
133
|
|
@@ -175,7 +194,7 @@ describe("Jax.Util", function() {
|
|
175
194
|
});
|
176
195
|
});
|
177
196
|
|
178
|
-
describe("with a
|
197
|
+
describe("with a object left and array right", function() {
|
179
198
|
beforeEach(function() { normalized = Jax.Util.normalizeOptions({p:{"x":20,"y":40,"z":60}}, {p:[1,2,3]}); });
|
180
199
|
it("should merge both into a gen object", function() {
|
181
200
|
expect(Object.isArray(normalized.p)).toBeFalsy();
|
@@ -37,6 +37,15 @@ describe "Rake Tasks:" do
|
|
37
37
|
Dir.chdir File.expand_path('..', pwd)
|
38
38
|
end
|
39
39
|
|
40
|
+
context "jax:generate_files" do
|
41
|
+
before(:each) { rake('jax:generate_files') }
|
42
|
+
subject { File.read(File.expand_path('tmp/version_check.js')) }
|
43
|
+
|
44
|
+
it "should do a version check" do
|
45
|
+
subject.should =~ /jax:update/
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
40
49
|
context "jax:package" do
|
41
50
|
before(:each) { rake('jax:package') }
|
42
51
|
|
@@ -47,6 +56,10 @@ describe "Rake Tasks:" do
|
|
47
56
|
File.should exist('pkg/images/test.png')
|
48
57
|
end
|
49
58
|
|
59
|
+
it "should not do a version check" do
|
60
|
+
subject.should_not =~ /jax:update/
|
61
|
+
end
|
62
|
+
|
50
63
|
it "should contain views" do
|
51
64
|
subject.should =~ /Jax.views.push\('welcome\/index'/
|
52
65
|
end
|
data/src/jax/context.js
CHANGED
@@ -384,7 +384,7 @@ Jax.Context = (function() {
|
|
384
384
|
var error = this.glGetError();
|
385
385
|
if (error != GL_NO_ERROR)
|
386
386
|
{
|
387
|
-
var str = "GL error in "+this.canvas.id+": "+error;
|
387
|
+
var str = "GL error in "+this.canvas.id+": "+error+" ("+Jax.Util.enumName(error)+")";
|
388
388
|
error = new Error(str);
|
389
389
|
var message = error;
|
390
390
|
if (error.stack)
|
data/src/jax/core/util.js
CHANGED
@@ -41,18 +41,25 @@ Jax.Util = {
|
|
41
41
|
**/
|
42
42
|
vectorize: function(data) {
|
43
43
|
if (data) {
|
44
|
-
var res = vec3.create();
|
44
|
+
var res = [];//vec3.create();
|
45
45
|
if (typeof(data) == "string") {
|
46
46
|
var components = data.split(/[,\s]+/);
|
47
|
-
if (components.length >=
|
48
|
-
for (var i = 0; i <
|
47
|
+
if (components.length >= 2) {
|
48
|
+
for (var i = 0; i < components.length; i++)
|
49
49
|
res[i] = parseFloat(components[i]);
|
50
50
|
}
|
51
51
|
return res;
|
52
52
|
}
|
53
53
|
if (data.length && data.length >= 3) return vec3.set(data, res);
|
54
|
-
if (
|
55
|
-
if ((res[0] = data
|
54
|
+
else if (data.length == 2) return [data[0], data[1]];
|
55
|
+
if ((res[0] = data.x) != undefined && (res[1] = data.y) != undefined) {
|
56
|
+
if (data.z != undefined) res[2] = data.z;
|
57
|
+
return res;
|
58
|
+
}
|
59
|
+
if ((res[0] = data[0]) != undefined && (res[1] = data[1]) != undefined) {
|
60
|
+
if (data[2] != undefined) res[2] = data[2];
|
61
|
+
return res;
|
62
|
+
}
|
56
63
|
}
|
57
64
|
throw new Error("Input argument for Jax.Util.vectorize not recognized: "+JSON.stringify(data));
|
58
65
|
},
|
data/src/jax/mvc/model.js
CHANGED
@@ -5,12 +5,64 @@ Jax.Scene.LightManager = (function() {
|
|
5
5
|
initialize: function(context) {
|
6
6
|
this.context = context;
|
7
7
|
this._lights = [];
|
8
|
+
this.objects = [];
|
9
|
+
},
|
10
|
+
|
11
|
+
addObject: function(obj) {
|
12
|
+
this.objects.push(obj);
|
13
|
+
for (var j = 0; j < this._lights.length; j++)
|
14
|
+
if (obj.isShadowCaster())
|
15
|
+
this._lights[j].registerCaster(obj);
|
16
|
+
this.recalculateBoundingRadius();
|
17
|
+
},
|
18
|
+
|
19
|
+
removeObject: function(obj) {
|
20
|
+
if (this.objects[obj]) {
|
21
|
+
var o = this.objects[obj];
|
22
|
+
this.objects.splice(obj, 1);
|
23
|
+
for (var j = 0; j < this._lights.length; j++)
|
24
|
+
if (o.isShadowCaster())
|
25
|
+
this._lights[j].unregisterCaster(o);
|
26
|
+
this.recalculateBoundingRadius();
|
27
|
+
return o;
|
28
|
+
}
|
29
|
+
for (var i = 0; i < this.objects.length; i++)
|
30
|
+
if (this.objects[i] == obj)
|
31
|
+
return this.removeObject(obj);
|
32
|
+
},
|
33
|
+
|
34
|
+
getShadowCasters: function() {
|
35
|
+
var ret = [];
|
36
|
+
for (var i = 0; i < this.objects.length; i++) {
|
37
|
+
if (this.objects[i].isShadowCaster())
|
38
|
+
ret.push(this.objects[i]);
|
39
|
+
}
|
40
|
+
return ret;
|
8
41
|
},
|
9
42
|
|
10
43
|
add: function(light) {
|
11
44
|
if (this._lights.length == Jax.max_lights)
|
12
45
|
throw new Error("Maximum number of light sources in a scene has been exceeded! Try removing some first.");
|
46
|
+
for (var i = 0; i < this.objects.length; i++) {
|
47
|
+
if (this.objects[i].isShadowCaster())
|
48
|
+
light.registerCaster(this.objects[i]);
|
49
|
+
}
|
13
50
|
this._lights.push(light);
|
51
|
+
light.boundingRadius = this.boundingRadius || 0;
|
52
|
+
},
|
53
|
+
|
54
|
+
recalculateBoundingRadius: function() {
|
55
|
+
var boundingRadius = null;
|
56
|
+
var i, j;
|
57
|
+
for (i = 0; i < this.objects.length; i++) {
|
58
|
+
j = vec3.length(this.objects[i].camera.getPosition()) + this.objects[i].getBoundingSphereRadius();
|
59
|
+
if (boundingRadius == null || boundingRadius < j)
|
60
|
+
boundingRadius = j;
|
61
|
+
}
|
62
|
+
this.boundingRadius = boundingRadius = boundingRadius || 0;
|
63
|
+
|
64
|
+
for (i = 0; i < this._lights.length; i++)
|
65
|
+
this._lights[i].boundingRadius = boundingRadius;
|
14
66
|
},
|
15
67
|
|
16
68
|
enable: function() { this.enabled = true; },
|
@@ -37,60 +89,21 @@ Jax.Scene.LightManager = (function() {
|
|
37
89
|
return result;
|
38
90
|
},
|
39
91
|
|
40
|
-
illuminate: function(context,
|
92
|
+
illuminate: function(context, options) {
|
93
|
+
// used by individual light sources
|
41
94
|
options = Jax.Util.normalizeOptions(options, {});
|
42
95
|
|
43
96
|
// Use alpha blending for the first pass, and additive blending for subsequent passes.
|
44
97
|
this.context.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
45
|
-
for (var i = 0; i < this._lights.length; i++) {
|
46
|
-
for (var j = 0; j < objects.length; j++) {
|
47
|
-
this._current_light = i;
|
48
|
-
options.model_index = j;
|
49
|
-
|
50
|
-
/* TODO optimization: see if objects[j] is even affected by this._lights[i] (based on attenuation) */
|
51
|
-
if (objects[j].isLit())
|
52
|
-
objects[j].render(context, options);
|
53
|
-
}
|
54
|
-
this.context.glBlendFunc(GL_ONE, GL_ONE);
|
55
|
-
}
|
56
|
-
delete this._current_light;
|
57
|
-
},
|
58
|
-
|
59
|
-
ambient: function(context, objects, options) {
|
60
|
-
options = Jax.Util.normalizeOptions(options, {});
|
61
|
-
|
62
98
|
for (var i = 0; i < this._lights.length; i++) {
|
63
99
|
this._current_light = i;
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
/* TODO optimization: see if objects[j] is even affected by this._lights[i] (based on attenuation) */
|
68
|
-
if (objects[j].isLit())
|
69
|
-
objects[j].render(context, options);
|
70
|
-
}
|
71
|
-
}
|
72
|
-
delete this._current_light;
|
73
|
-
},
|
74
|
-
|
75
|
-
updateShadowMaps: function(context, objects) {
|
76
|
-
var boundingRadius = null;
|
77
|
-
var i, j;
|
78
|
-
for (i = 0; i < objects.length; i++) {
|
79
|
-
j = vec3.length(objects[i].camera.getPosition()) + objects[i].getBoundingSphereRadius();
|
80
|
-
if (boundingRadius == null || boundingRadius < j)
|
81
|
-
boundingRadius = j;
|
100
|
+
this._lights[i].render(context, this.objects, options);
|
101
|
+
if (i == 0) this.context.glBlendFunc(GL_ONE, GL_ONE);
|
82
102
|
}
|
83
|
-
boundingRadius = boundingRadius || 0;
|
84
103
|
|
85
|
-
|
86
|
-
// context.glPolygonOffset(2,2);
|
87
|
-
// context.glEnable(GL_POLYGON_OFFSET_FILL);
|
88
|
-
for (i = 0; i < this._lights.length; i++)
|
89
|
-
this._lights[i].updateShadowMap(context, boundingRadius, objects);
|
90
|
-
// context.glDisable(GL_POLYGON_OFFSET_FILL);
|
91
|
-
// context.glPolygonOffset(0.0, 0.0);
|
104
|
+
delete this._current_light;
|
92
105
|
},
|
93
|
-
|
106
|
+
|
94
107
|
getDirection: function(index) { return this.getLight(index).getDirection(); },
|
95
108
|
|
96
109
|
getPosition: function(index) { return this.getLight(index).getPosition(); },
|
@@ -49,6 +49,9 @@ Jax.Scene.LightSource = (function() {
|
|
49
49
|
data.color.diffuse = Jax.Util.colorize(data.color.diffuse);
|
50
50
|
data.color.specular= Jax.Util.colorize(data.color.specular);
|
51
51
|
$super(data);
|
52
|
+
|
53
|
+
var self = this;
|
54
|
+
this.camera.addEventListener('matrixUpdated', function() { self.invalidate(); });
|
52
55
|
|
53
56
|
this.spotExponent = this.spot_exponent;
|
54
57
|
delete this.spot_exponent;
|
@@ -125,13 +128,48 @@ Jax.Scene.LightSource = (function() {
|
|
125
128
|
return this.shadowMatrix;
|
126
129
|
},
|
127
130
|
|
131
|
+
registerCaster: function(object) {
|
132
|
+
var self = this;
|
133
|
+
function updated() { self.invalidate(); }
|
134
|
+
object.camera.addEventListener('matrixUpdated', updated);
|
135
|
+
this.invalidate();
|
136
|
+
},
|
137
|
+
|
138
|
+
unregisterCaster: function(object) {
|
139
|
+
/* FIXME remove the shadowmap event listener from object's camera matrix */
|
140
|
+
},
|
141
|
+
|
128
142
|
isShadowcaster: function() { return this.shadowcaster; },
|
129
143
|
|
130
144
|
getDPShadowNear: function() { setupProjection(this); return this.camera.projection.near; },
|
131
145
|
|
132
146
|
getDPShadowFar: function() { setupProjection(this); return this.camera.projection.far; },
|
133
147
|
|
134
|
-
|
148
|
+
invalidate: function() { this.valid = false; },
|
149
|
+
|
150
|
+
render: function(context, objects, options) {
|
151
|
+
if (!this.valid) {
|
152
|
+
var real_pass = context.current_pass;
|
153
|
+
/* shadowgen pass */
|
154
|
+
context.current_pass = Jax.Scene.SHADOWMAP_PASS;
|
155
|
+
this.updateShadowMap(context, this.boundingRadius, objects, options);
|
156
|
+
this.valid = true;
|
157
|
+
context.current_pass = real_pass;
|
158
|
+
}
|
159
|
+
|
160
|
+
for (var j = 0; j < objects.length; j++) {
|
161
|
+
options.model_index = j;
|
162
|
+
|
163
|
+
/* TODO optimization: see if objects[j] is even affected by this light (based on attenuation) */
|
164
|
+
if (objects[j].isLit()) // it could be unlit but still in array if it casts a shadow
|
165
|
+
objects[j].render(context, options);
|
166
|
+
}
|
167
|
+
},
|
168
|
+
|
169
|
+
updateShadowMap: function(context, sceneBoundingRadius, objects, render_options) {
|
170
|
+
// we can't afford to taint the original options
|
171
|
+
render_options = Jax.Util.normalizeOptions(render_options, {});
|
172
|
+
|
135
173
|
setupProjection(this);
|
136
174
|
|
137
175
|
var self = this;
|
@@ -163,6 +201,9 @@ Jax.Scene.LightSource = (function() {
|
|
163
201
|
context.glPolygonOffset(2.0, 2.0);
|
164
202
|
|
165
203
|
context.pushMatrix(function() {
|
204
|
+
render_options.direction = 1;
|
205
|
+
render_options.material = paraboloid_depthmap;
|
206
|
+
|
166
207
|
self.framebuffers[0].bind(context, function() {
|
167
208
|
// front paraboloid
|
168
209
|
self.framebuffers[0].viewport(context);
|
@@ -171,17 +212,19 @@ Jax.Scene.LightSource = (function() {
|
|
171
212
|
mat4.set(context.getInverseViewMatrix(), sm);
|
172
213
|
|
173
214
|
for (var i = 0; i < objects.length; i++) {
|
174
|
-
objects[i].render(context,
|
215
|
+
objects[i].render(context, render_options);
|
175
216
|
}
|
176
217
|
});
|
177
218
|
|
219
|
+
render_options.direction = -1;
|
220
|
+
|
178
221
|
self.framebuffers[1].bind(context, function() {
|
179
222
|
// back paraboloid
|
180
223
|
self.framebuffers[1].viewport(context);
|
181
224
|
context.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
182
225
|
context.loadViewMatrix(self.camera.getTransformationMatrix());
|
183
226
|
for (var i = 0; i < objects.length; i++) {
|
184
|
-
objects[i].render(context,
|
227
|
+
objects[i].render(context, render_options);
|
185
228
|
}
|
186
229
|
});
|
187
230
|
|
@@ -197,6 +240,8 @@ Jax.Scene.LightSource = (function() {
|
|
197
240
|
return;
|
198
241
|
}
|
199
242
|
|
243
|
+
render_options.material = "depthmap";
|
244
|
+
|
200
245
|
this.framebuffers[0].bind(context, function() {
|
201
246
|
self.framebuffers[0].viewport(context);
|
202
247
|
context.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
@@ -214,7 +259,7 @@ Jax.Scene.LightSource = (function() {
|
|
214
259
|
context.glEnable(GL_POLYGON_OFFSET_FILL);
|
215
260
|
context.glPolygonOffset(2.0, 2.0);
|
216
261
|
for (var i = 0; i < objects.length; i++) {
|
217
|
-
objects[i].render(context,
|
262
|
+
objects[i].render(context, render_options);
|
218
263
|
}
|
219
264
|
context.glDisable(GL_POLYGON_OFFSET_FILL);
|
220
265
|
context.glEnable(GL_BLEND);
|