jax 0.0.0.3 → 0.0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/LICENSE +19 -0
  2. data/README.rdoc +32 -15
  3. data/Rakefile +8 -2
  4. data/builtin/shaders/functions/lights.ejs +19 -31
  5. data/builtin/shaders/lighting/fragment.ejs +20 -14
  6. data/builtin/shaders/normal_map/manifest.yml +2 -2
  7. data/builtin/shaders/texture/manifest.yml +2 -2
  8. data/guides/assets/images/getting_started/dungeon-complete.png +0 -0
  9. data/guides/assets/images/getting_started/dungeon-normal-map.png +0 -0
  10. data/guides/assets/images/getting_started/dungeon-rainbow-textured.png +0 -0
  11. data/guides/assets/images/getting_started/dungeon-rainbow.png +0 -0
  12. data/guides/assets/images/getting_started/dungeon-textured-lighting.png +0 -0
  13. data/guides/assets/images/getting_started/dungeon-textured.png +0 -0
  14. data/guides/assets/images/getting_started/teapot-red-directional-point.png +0 -0
  15. data/guides/assets/images/getting_started/teapot-red-directional.png +0 -0
  16. data/guides/assets/images/getting_started/teapot-red-nolight.png +0 -0
  17. data/guides/assets/images/getting_started/teapot-red-spot-point-directional.png +0 -0
  18. data/guides/assets/images/getting_started/teapot-white.png +0 -0
  19. data/guides/assets/images/getting_started/teapot-with-model.png +0 -0
  20. data/guides/source/getting_started.textile +80 -39
  21. data/guides/source/index.html.erb +5 -1
  22. data/guides/source/matrices.textile +5 -0
  23. data/lib/jax/generators/app/app_generator.rb +16 -5
  24. data/lib/jax/generators/app/templates/public/javascripts/jax.js +27 -11
  25. data/lib/jax/generators/commands.rb +17 -4
  26. data/lib/jax/generators/material/material_generator.rb +1 -1
  27. data/lib/jax/generators/shader/USAGE +4 -0
  28. data/lib/jax/generators/shader/shader_generator.rb +71 -0
  29. data/lib/jax/generators/shader/templates/common.ejs.tt +16 -0
  30. data/lib/jax/generators/shader/templates/fragment.ejs.tt +8 -0
  31. data/lib/jax/generators/shader/templates/manifest.yml.tt +15 -0
  32. data/lib/jax/generators/shader/templates/material.js.tt +28 -0
  33. data/lib/jax/generators/shader/templates/spec.js.tt +28 -0
  34. data/lib/jax/generators/shader/templates/vertex.ejs.tt +10 -0
  35. data/lib/jax/version.rb +1 -1
  36. data/spec/javascripts/jax/webgl/shader_chain_spec.js +1 -1
  37. data/spec/javascripts/{jax/builtin/materials → shaders}/core_materials_spec.js +0 -0
  38. data/spec/javascripts/{jax/builtin/materials → shaders}/dual_paraboloid_spec.js +0 -0
  39. data/spec/javascripts/{jax/builtin/materials → shaders}/fog_spec.js +0 -0
  40. data/spec/javascripts/{jax/builtin/materials → shaders}/lighting_spec.js +0 -0
  41. data/spec/javascripts/{jax/builtin/materials → shaders}/normal_map_spec.js +0 -0
  42. data/spec/javascripts/{jax/builtin/materials → shaders}/shadow_map_spec.js +0 -0
  43. data/spec/javascripts/{jax/builtin/materials → shaders}/texture_spec.js +0 -0
  44. data/src/jax/core/matrix_stack.js +7 -3
  45. data/src/jax/webgl/core/framebuffer.js +5 -0
  46. data/src/jax/webgl/scene/light_manager.js +4 -1
  47. data/src/jax/webgl/shader.js +11 -1
  48. data/src/jax/webgl/shader/manifest.js +6 -6
  49. data/src/jax/webgl/shader_chain.js +9 -2
  50. data/src/jax/webgl/world.js +8 -4
  51. metadata +40 -18
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Colin MacKenzie IV
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -1,11 +1,3 @@
1
- == Important
2
-
3
- JAX is a working title and is subject to change. Also, it is under heavy development and is largely incomplete.
4
- Keep in mind that this README represents how JAX is _meant_ to work upon completion, not necessarily how it would
5
- work if you were to clone the git repository right now.
6
-
7
- <b>I reserve the right to commit broken code until version 0.0.1 is officially released.</b>
8
-
9
1
  == JAX
10
2
 
11
3
  JAX is a framework for developing rich WebGL-enabled applications using JavaScript and Ruby.
@@ -18,15 +10,40 @@ Other than that, JAX requires a few ruby gems which will be retrieved automatica
18
10
 
19
11
  == Getting Started
20
12
 
21
- If you're unfamiliar with Jax, a good place to start would be at the {Jax Wiki}[http://github.com/sinisterchipmunk/jax/wiki]
22
- where you can find tutorials, documentation, and tips.
13
+ By far the best place to go if you want to dive into Jax is the {Jax Guides}[http://guides.jaxgl.com]. These are comprehensive guided tours of the framework, and cover pretty much anything you can think of doing. In particular, the {Getting Started Guide}[http://guides.jaxgl.com/getting_started.html] is laid out in an easy-to-follow tutorial format.
14
+
15
+ Another good place to look around is the {Jax Wiki}[http://github.com/sinisterchipmunk/jax/wiki], where Jax developers (including yourself!) can share tips and tricks with one another.
23
16
 
24
- <b>Please be aware that, like Jax itself, the Wiki is a work in progress and will be updated periodically to reflect the
25
- latest code changes.</b>
17
+ The {Forums}[http://jaxgl.com/forums] are a great place to get involved in the Jax community, and are a good place to go for help or general discussion.
18
+
19
+ The {Jax Blog}[http://blog.jaxgl.com] is where the latest news and developments-in-progress will be posted, so if you keep an eye on you'll always be in the know.
20
+
21
+ Finally, you can always contact me, the developer, on Twitter as {@sinisterchipmnk}[http://twitter.com/sinisterchipmnk] or {sinisterchipmunk on Github}[http://github.com/sinisterchipmunk].
26
22
 
27
23
  == The Demo App
28
24
 
29
- This project includes an {example application}[https://github.com/sinisterchipmunk/jax/tree/master/spec/example_app],
30
- which is meant to represent a very basic Jax application. It provides a visual testbed for various aspects of Jax
31
- while simultaneously demonstrating key concepts such as event processing and resource management.
25
+ This project includes an {example application}[https://github.com/sinisterchipmunk/jax/tree/master/spec/example_app]. Over time, this example -- which was originally meant to be a guide for the developer to follow and test against while developing Jax itself -- has become the standard testbed for the visual elements of Jax, such as the built-in shaders, which can't be tested without human interaction. Feel free to take a look at the example app if you're up for some eye candy.
26
+
27
+ == Helping Out
28
+
29
+ Anyone interested in doing so is more than welcome -- nay, _encouraged_ -- to fork this project on {Github}[http://github.com/sinisterchipmunk/jax].
30
+
31
+ === How to Contribute
32
+
33
+ 1. Fork Jax.
34
+ 2. Check out a new branch. Name it something representative of the changes you'll make.
35
+ 3. Write a failing test case to demonstrate the need for your new code.
36
+ 4. Update Jax to work with your failing test case.
37
+ 5. Send me a pull request explaining (in detail, please) what you did and why you did it.
38
+ 6. If it's in line with the long-term plans for Jax, I'll review the commits, merge them with the main project and give you credit.
39
+
40
+ === Notes
41
+
42
+ * When making code changes, please don't update the version number. I'll do that when it's time to actually release some code.
43
+ * If you do not wished to be credited for your contribution, let me know.
44
+ * Feel free to fix or update the documentation and/or the Jax guides. They're part of the project, after all.
45
+ * If your code change is public-facing, please _do_ update the documentation with how to use the new features. You know your own code better than anyone else.
46
+
47
+ == License
32
48
 
49
+ Jax is released under the MIT license.
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ $JAX_RAKE = true
5
5
  begin
6
6
  require 'bundler'
7
7
  Bundler::GemHelper.install_tasks
8
+ Bundler.setup
8
9
  rescue LoadError
9
10
  puts " *** You don't seem to have Bundler installed. ***"
10
11
  puts " Please run the following command:"
@@ -66,7 +67,7 @@ task :compile do
66
67
  end
67
68
 
68
69
  puts "generated #{File.expand_path "dist/jax.js", '.'}"
69
- cp File.join(File.dirname(__FILE__), "dist/jax.js"),
70
+ cp File.join(File.dirname(__FILE__), "dist/jax.js"),
70
71
  File.join(File.dirname(__FILE__), "lib/jax/generators/app/templates/public/javascripts/jax.js")
71
72
 
72
73
  puts "(project built)"
@@ -76,6 +77,8 @@ desc "compile and minify Jax into dist/jax.js and dist/jax-min.js"
76
77
  task :minify => :compile do
77
78
  puts "(minifying...)"
78
79
  if system("java", "-jar", File.join(File.dirname(__FILE__), "vendor/yuicompressor-2.4.2.jar"), "dist/jax.js", "-o", "dist/jax-min.js")
80
+ cp File.join(File.dirname(__FILE__), "dist/jax-min.js"),
81
+ File.join(File.dirname(__FILE__), "lib/jax/generators/app/templates/public/javascripts/jax.js")
79
82
  puts "(done.)"
80
83
  else
81
84
  puts "(Error while minifying!)"
@@ -113,7 +116,6 @@ namespace :doc do
113
116
  end
114
117
 
115
118
  namespace :guides do
116
- desc 'Generate guides (for authors), use ONLY=foo to process just "foo.textile"'
117
119
  task :generate do
118
120
  rm_rf "guides/output"
119
121
  ENV["WARN_BROKEN_LINKS"] = "1" # authors can't disable this
@@ -142,3 +144,7 @@ task :guides => 'guides:generate'
142
144
  task :jasmine => :compile
143
145
  task :build => :compile
144
146
  task :default => :compile
147
+
148
+ # we should do this before v0.0.1 but will make issues harder to track,
149
+ # so let's hold off while in prerelease :
150
+ # task :release => :minify
@@ -31,22 +31,19 @@ void DirectionalLight(in vec3 normal,
31
31
  inout vec4 diffuse,
32
32
  inout vec4 specular)
33
33
  {
34
- if (PASS_TYPE == <%=Jax.Scene.AMBIENT_PASS%>)
35
- ambient += LIGHT_AMBIENT;
36
- else {
37
- vec3 nLDir = normalize(vnMatrix * -normalize(LIGHT_DIRECTION));
38
- vec3 halfVector = normalize(nLDir + vec3(0,0,1));
39
- float pf;
34
+ vec3 nLDir = normalize(vnMatrix * -normalize(LIGHT_DIRECTION));
35
+ vec3 halfVector = normalize(nLDir + vec3(0,0,1));
36
+ float pf;
40
37
 
41
- float NdotD = max(0.0, dot(normal, nLDir));
42
- float NdotHV = max(0.0, dot(normal, halfVector));
38
+ float NdotD = max(0.0, dot(normal, nLDir));
39
+ float NdotHV = max(0.0, dot(normal, halfVector));
43
40
 
44
- if (NdotD == 0.0) pf = 0.0;
45
- else pf = pow(NdotHV, materialShininess);
41
+ if (NdotD == 0.0) pf = 0.0;
42
+ else pf = pow(NdotHV, materialShininess);
46
43
 
47
- diffuse += LIGHT_DIFFUSE * NdotD;
48
- specular += LIGHT_SPECULAR * pf;
49
- }
44
+ ambient += LIGHT_AMBIENT;
45
+ diffuse += LIGHT_DIFFUSE * NdotD;
46
+ specular += LIGHT_SPECULAR * pf;
50
47
  }
51
48
 
52
49
  /* Use when attenuation != (1,0,0) */
@@ -73,12 +70,9 @@ void PointLightWithAttenuation(in vec3 ecPosition3,
73
70
  if (NdotD == 0.0) pf = 0.0;
74
71
  else pf = pow(NdotHV, materialShininess);
75
72
 
76
- if (PASS_TYPE == <%=Jax.Scene.AMBIENT_PASS%>)
77
- ambient += LIGHT_AMBIENT * attenuation;
78
- else {
79
- diffuse += LIGHT_DIFFUSE * NdotD * attenuation;
80
- specular += LIGHT_SPECULAR * pf * attenuation;
81
- }
73
+ ambient += LIGHT_AMBIENT * attenuation;
74
+ diffuse += LIGHT_DIFFUSE * NdotD * attenuation;
75
+ specular += LIGHT_SPECULAR * pf * attenuation;
82
76
  }
83
77
 
84
78
  /* Use for better performance when attenuation == (1,0,0) */
@@ -105,12 +99,9 @@ void PointLightWithoutAttenuation(in vec3 ecPosition3,
105
99
  if (NdotD == 0.0) pf = 0.0;
106
100
  else pf = pow(NdotHV, materialShininess);
107
101
 
108
- if (PASS_TYPE == <%=Jax.Scene.AMBIENT_PASS%>)
109
- ambient += LIGHT_AMBIENT;
110
- else {
111
- diffuse += LIGHT_DIFFUSE * NdotD;
112
- specular += LIGHT_SPECULAR * pf;
113
- }
102
+ ambient += LIGHT_AMBIENT;
103
+ diffuse += LIGHT_DIFFUSE * NdotD;
104
+ specular += LIGHT_SPECULAR * pf;
114
105
  }
115
106
 
116
107
  void SpotLight(in vec3 ecPosition3,
@@ -146,10 +137,7 @@ void SpotLight(in vec3 ecPosition3,
146
137
  if (NdotD == 0.0) pf = 0.0;
147
138
  else pf = pow(NdotHV, materialShininess);
148
139
 
149
- if (PASS_TYPE == <%=Jax.Scene.AMBIENT_PASS%>)
150
- ambient += LIGHT_AMBIENT * attenuation;
151
- else {
152
- diffuse += LIGHT_DIFFUSE * NdotD * attenuation;
153
- specular += LIGHT_SPECULAR * pf * attenuation;
154
- }
140
+ ambient += LIGHT_AMBIENT * attenuation;
141
+ diffuse += LIGHT_DIFFUSE * NdotD * attenuation;
142
+ specular += LIGHT_SPECULAR * pf * attenuation;
155
143
  }
@@ -12,23 +12,29 @@ void main(inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
12
12
  PointLightWithoutAttenuation(vSurfacePos, nNormal, _ambient, _diffuse, _specular);
13
13
  else
14
14
  PointLightWithAttenuation(vSurfacePos, nNormal, _ambient, _diffuse, _specular);
15
- else
16
- if (LIGHT_TYPE == <%=Jax.SPOT_LIGHT%>)
17
- SpotLight(vSurfacePos, nNormal, _ambient, _diffuse, _specular);
18
- else
19
- { // error condition, output 100% red
20
- gl_FragColor = vec4(1,0,0,1);
21
- return;
22
- }
15
+ else
16
+ if (LIGHT_TYPE == <%=Jax.SPOT_LIGHT%>)
17
+ SpotLight(vSurfacePos, nNormal, _ambient, _diffuse, _specular);
18
+ else
19
+ { // error condition, output 100% red
20
+ gl_FragColor = vec4(1,0,0,1);
21
+ return;
22
+ }
23
23
  } else {
24
24
  _ambient = vec4(1,1,1,1);
25
25
  _diffuse = _specular = vec4(0,0,0,0);
26
26
  }
27
27
 
28
- // is this correct??
29
- if (_ambient.a != 0.0) _ambient.a = 1.0;
30
-
31
- ambient *= _ambient;
32
- diffuse *= _diffuse;
33
- specular *= _specular;
28
+ /*
29
+ Light colors will be multiplied by material colors. Light can't really be transparent,
30
+ so we'll use alpha to represent intensity. This means we must multiply resultant light
31
+ colors by light alpha, and then hard-code alpha 1 to avoid polluting transparency.
32
+
33
+ The reason we use LIGHT_*.a instead of _*.a is because _*.a has been tainted by attenuation.
34
+ A light's intensity, regardless of distance or relative brightness, has not actually changed;
35
+ attenuation has been factored into color already; we don't want to square the atten amt.
36
+ */
37
+ ambient *= vec4(_ambient.rgb * LIGHT_AMBIENT.a, 1.0);
38
+ diffuse *= vec4(_diffuse.rgb * LIGHT_DIFFUSE.a, 1.0);
39
+ specular *= vec4(_specular.rgb * LIGHT_SPECULAR.a, 1.0);
34
40
  }
@@ -6,8 +6,8 @@ options:
6
6
  scale_x: 1.0
7
7
  scale_y: 1.0
8
8
  generate_mipmap: true
9
- min_filter: GL_NEAREST
10
- mag_filter: GL_NEAREST
9
+ min_filter: GL_LINEAR
10
+ mag_filter: GL_LINEAR
11
11
  mipmap_hint: GL_DONT_CARE
12
12
  format: GL_RGBA
13
13
  data_type: GL_UNSIGNED_BYTE
@@ -6,8 +6,8 @@ options:
6
6
  scale_x: 1.0
7
7
  scale_y: 1.0
8
8
  generate_mipmap: true
9
- min_filter: GL_NEAREST
10
- mag_filter: GL_NEAREST
9
+ min_filter: GL_LINEAR
10
+ mag_filter: GL_LINEAR
11
11
  mipmap_hint: GL_DONT_CARE
12
12
  format: GL_RGBA
13
13
  data_type: GL_UNSIGNED_BYTE
@@ -54,6 +54,11 @@ h3. Creating a New Jax Project
54
54
 
55
55
  This guide will walk you through creating a sample application from scratch. The application will create a 3D "dungeon" that the player can move around in. It will be a first-person application, rendered as if through the eyes of the player's character.
56
56
 
57
+ Here's a screenshot of the finished dungeon scene:
58
+
59
+ !images/getting_started/dungeon-complete.png(The Dungeon)!
60
+
61
+
57
62
  h4. Installing Jax
58
63
 
59
64
  The first step to creating any Jax application is to make sure Jax itself is installed. Assuming you have already set up its primary dependencies, "Ruby":http://www.ruby-lang.org and "RubyGems":http://rubyforge.org/frs/?group_id=126, this should be as simple as running the following command:
@@ -178,6 +183,8 @@ Therefore, the above code will create a new Teapot object, position it 5 units i
178
183
 
179
184
  Reload your suite again, and you'll see the fruits of your labor!
180
185
 
186
+ !images/getting_started/teapot-white.png(The Default Teapot)!
187
+
181
188
  h5. Using Materials for Color
182
189
 
183
190
  We have a teapot, but we don't have a very _impressive_ teapot. In fact, it looks rather flat, uninspiring and _white_.
@@ -191,7 +198,7 @@ This will generate a Jax material. By default, Jax will also add in support for
191
198
 
192
199
  TIP: This guide won't cover Jax materials in depth, but they're very powerful and very versatile. For more information regarding Jax materials, see the "Jax Material Guide":materials.html.
193
200
 
194
- Edit the newly-generated material file, +app/resources/material/teapot.yml+. Under +ambient+ coloring, change the +green+ and +blue+ values to 0.0, and leave the +red+ and +alpha+ values at 1.0. This will produce a completely opaque, red teapot:
201
+ Edit the newly-generated material file, +app/resources/material/teapot.yml+. Under +ambient+ coloring, change the +green+ and +blue+ values to 0.0, and leave the +red+ and +alpha+ values at 1.0.
195
202
 
196
203
  <yaml>
197
204
  ambient:
@@ -210,10 +217,13 @@ Again, edit the +app/controllers/teapot_controller.js+ file and alter this line:
210
217
  Replace it with the following:
211
218
 
212
219
  <js>
213
- mesh: new Jax.Mesh.Teapot({ material: Material.find("teapot") });
220
+ mesh: new Jax.Mesh.Teapot({ material: Material.find("teapot") })
214
221
  </js>
215
222
 
216
- Reload your suite again, and the teapot will turn red.
223
+ This will produce a completely opaque, red teapot. It looks depressingly two-dimensional because it's composed entirely of a single color. Next, we'll make it look more like the 3D object it really is!
224
+
225
+ <img src="images/getting_started/teapot-red-nolight.png" style="width:300px;height:200px;float:left;margin-right:2em;"/>
226
+ <img src="images/getting_started/teapot-red-spot-point-directional.png" style="width:300px;height:200px;clear:right;"/>
217
227
 
218
228
  h4. Using Light Sources
219
229
 
@@ -235,25 +245,33 @@ Let's start simple by adding a directional light to our scene. First, from the c
235
245
  $ jax generate light sun directional
236
246
  </shell>
237
247
 
238
- Edit the file it generates, +app/resources/light_sources/sun.yml+, and change the +direction+ field to look like this:
248
+ Next, we need the controller to add it to the scene. Edit your controller file at +app/controllers/teapot_controller.js+ and add the following line to the +index+ action:
249
+
250
+ <js>
251
+ index: function() {
252
+ // ...
253
+ this.world.addLightSource(LightSource.find("sun"));
254
+ }
255
+ </js>
256
+
257
+ Now edit the file the generator created, +app/resources/light_sources/sun.yml+, and change the +direction+ field to look like this:
239
258
 
240
259
  <yaml>
241
260
  direction:
242
261
  x: -1
243
262
  y: -1
244
- z: -1
263
+ z: 1
245
264
  </yaml>
246
265
 
247
- This tells the light to shine left, down, and forward relative to world space. (Remember that, currently, our camera is unmodified, so world space and camera space are the same thing. When we get around to rotating the camera, the difference between camera and world space will become more important.)
248
-
249
- Now that we have defined our light, we just need the controller to add it to the scene. Edit your controller file at +app/controllers/teapot_controller.js+ and add the following line to the +index+ action:
266
+ This tells the light to shine left, down, and backward relative to world space.
250
267
 
251
- <js>
252
- this.world.addLightSource(LightSource.find("sun"));
253
- </js>
268
+ INFO: Remember that, currently, our camera is unmodified, so world space and camera space are the same thing. When we get around to rotating the camera, the difference between camera and world space will become more important. For more information about the various spaces and the differences between them, take a look at the "Matrices Guide":matrices.html.
254
269
 
255
270
  Reload your scene, and you should finally be starting to see some detail!
256
271
 
272
+ !images/getting_started/teapot-red-directional.png(Teapot With Directional Light)!
273
+
274
+
257
275
  h5. Point Lights
258
276
 
259
277
  These are omnidirectional lights that have an origin at a specific point in world space. They shine in all directions from their position, and every object (indeed, every pixel) is lit at a different angle. In the real world, this is technically the only kind of light.
@@ -264,7 +282,16 @@ Point lights are useful for simulating relatively small light sources like candl
264
282
  $ jax generate light candle point
265
283
  </shell>
266
284
 
267
- Edit the generated file, +app/resources/light_sources/candle.yml+, and change the +position+ field to look like this:
285
+ Again, add the light source to the scene from the controller +app/controllers/teapot_controller.js+:
286
+
287
+ <js>
288
+ index: function() {
289
+ // ...
290
+ this.world.addLightSource(LightSource.find("candle"));
291
+ }
292
+ </js>
293
+
294
+ And again, edit the generated file, +app/resources/light_sources/candle.yml+, and change the +position+ field to look like this:
268
295
 
269
296
  <yaml>
270
297
  position:
@@ -298,13 +325,10 @@ color:
298
325
  alpha: 1.0
299
326
  </yaml>
300
327
 
301
- The last step is, again, to add the light source to the scene from the controller +app/controllers/teapot_controller.js+:
328
+ Reload the scene again and you should see your candle's effect upon the teapot.
302
329
 
303
- <js>
304
- this.world.addLightSource(LightSource.find("candle"));
305
- </js>
330
+ !images/getting_started/teapot-red-directional-point.png(Teapot With Directional and Point Lights)!
306
331
 
307
- Reload the scene again and you should see your candle's effect upon the teapot.
308
332
 
309
333
  h5. Spot Lights
310
334
 
@@ -318,7 +342,16 @@ Generate the spot light in the same manner as the last two:
318
342
  $ jax generate light searchlight spot
319
343
  </shell>
320
344
 
321
- This time, we'll alter the position and direction to shine toward, but not directly upon, the teapot; we'll also alter the color so that the light is blue, the angle of the spotlight (that is, the width of the cone), and the spot exponent, which represents how fast light fades out from the center of the cone. With a spot exponent of zero, the spotlight's cone should be quite clearly defined.
345
+ Like the others, add this light to the scene in +app/controllers/teapot_controller.js+:
346
+
347
+ <js>
348
+ index: function() {
349
+ // ...
350
+ this.world.addLightSource(LightSource.find("searchlight"));
351
+ }
352
+ </js>
353
+
354
+ This time, we'll alter the position and direction to shine toward, but not directly upon, the teapot; we'll also alter the color, the angle of the spotlight (that is, the width of the cone), and the spot exponent, which represents how fast light fades out from the center of the cone. With a spot exponent of zero, the spotlight's cone should be quite clearly defined.
322
355
 
323
356
  The file to edit is +app/resources/light_sources/searchlight.yml+:
324
357
 
@@ -326,20 +359,20 @@ The file to edit is +app/resources/light_sources/searchlight.yml+:
326
359
  position:
327
360
  x: 0
328
361
  y: 0
329
- z: 2
362
+ z: -3.25
330
363
 
331
364
  direction:
332
- x: 0.35
333
- y: 0
365
+ x: 0.05
366
+ y: -0.025
334
367
  z: -1
335
368
 
336
369
  type: SPOT_LIGHT
337
370
 
338
371
  # the cone is approx. 20 degrees wide, in radians
339
- angle: 0.35
372
+ angle: 0.349
340
373
 
341
- # this light has very sharp edges.
342
- spot_exponent: 0
374
+ # this light has fairly sharp edges.
375
+ spot_exponent: 8
343
376
 
344
377
  attenuation:
345
378
  constant: 1.0
@@ -350,7 +383,7 @@ color:
350
383
  ambient:
351
384
  red: 0
352
385
  green: 0
353
- blue: 0.2
386
+ blue: 0.4
354
387
  alpha: 1
355
388
 
356
389
  diffuse:
@@ -361,27 +394,23 @@ color:
361
394
 
362
395
  specular:
363
396
  red: 0
364
- green: 0
365
- blue: 0.5
397
+ green: 1
398
+ blue: 0
366
399
  alpha: 1.0
367
400
  </yaml>
368
401
 
369
- Like the others, add this light to the scene in +app/controllers/teapot_controller.js+:
370
-
371
- <js>
372
- this.world.addLightSource(LightSource.find("searchlight"));
373
- </js>
374
-
375
- Once again, you're ready to reload the scene. Note how only half of the teapot has a blue tinge; the other half is unaffected. The blue is produced by the spotlight.
402
+ Once again, you're ready to reload the scene. Note how the spotlight is bright in the center, but begins to fade a little bit toward the edges. The amount of fading is controlled with the +spot_exponent+ setting. In general, a higher number will produce a spotlight that fades more quickly, while a lower number will produce sharper edges. A spotlight with a spot exponent of 0 will have extremely sharp edges.
376
403
 
377
404
  Take some time to alter the various lighting settings, above, and note the differences in the results.
378
405
 
379
406
  WARNING: Jax supports an arbitrary number of light sources; that is, there's no hard limit on how many lights you can have in your scene. However, be aware that the scene must be rendered once <em>for each light source</em>, so you can expect to take a significant performance hit by simply tossing lights around without carefully considering the implications. Always keep in mind the quality of the hardware you're targeting; the more light sources you activate, the lower the framerate on your clients' systems.
380
407
 
408
+ !images/getting_started/teapot-red-spot-point-directional.png(Teapot With Directional, Spot and Point Lights)!
409
+
410
+
381
411
  h4. Making the Most of Models
382
412
 
383
- So far, we've only made use of the controller and the view. (We've only actually altered the controller, because the
384
- view that Jax generates is fine for most applications.)
413
+ So far, we've only made use of the controller and the view. (We've only actually altered the controller, because the view that Jax generates is fine for most applications.)
385
414
 
386
415
  Now we'd like to add some lower-level business logic to our application. In particular, we'll make the teapot rotate in
387
416
  place. This sort of logic is exactly what models are designed to encapsulate.
@@ -1033,6 +1062,9 @@ end
1033
1062
 
1034
1063
  After making this change and reloading your Jax suite, you should be standing within (and able to walk / look around in) your new, brightly-colored Dungeon!
1035
1064
 
1065
+ !images/getting_started/dungeon-rainbow.png(A Brightly Colored Dungeon)!
1066
+
1067
+
1036
1068
  h3. Adding Texture
1037
1069
 
1038
1070
  The dungeon is functional, but it's not very believable. In fact, a rainbow-colored dungeon isn't much of a dungeon at all! We made each wall a starkly different color for the purposes of this tutorial, but realistically, you'd probably never do this. Instead, you'd make it look more like the environment you're targeting, and the most basic way to do this is with texturing.
@@ -1063,7 +1095,11 @@ Now edit the +app/resources/materials/dungeon.yml+ file. Scroll to the bottom, a
1063
1095
 
1064
1096
  Reload, and you'll see textured walls! However, all is not quite ideal. The walls of the dungeon are now textured, but they are still tinged with their original colors. This is because the per-vertex color data hasn't changed. Jax, receiving conflicting information about the mesh, has merged the two data sets. Actually, it's pretty normal for a graphics library to do this, because it allows you to do special coloring on a mesh irrespective of the textures used.
1065
1097
 
1066
- To undo the colored walls, simply edit the +app/models/dungeon.js+ file and replace all the 0's in calls to +colors.push(...)+ to 1's. Reload, and all of the walls should be the expected color.
1098
+ <strong>To undo the colored walls, simply edit the +app/models/dungeon.js+ file and replace all the 0's in calls to +colors.push(...)+ to 1's. Reload, and all of the walls should be the expected color.</strong>
1099
+
1100
+ <img src="images/getting_started/dungeon-rainbow-textured.png" style="width:300px;height:200px;margin-right:2em;float:left;" />
1101
+ <img src="images/getting_started/dungeon-textured.png" style="clear:right;width:300px;height:200px;" />
1102
+
1067
1103
 
1068
1104
  h3. Light Sources
1069
1105
 
@@ -1106,7 +1142,10 @@ addTorches: function(world) {
1106
1142
 
1107
1143
  What this code does is search through the map looking for light sources (denoted by an apostrophe). When it finds one, it instantiates a new point light form the +torch+ resource, sets its position and then adds it to the scene. Since all the walls and floors are offset by half a unit in each direction, the point light will be positioned directly in the middle of the hallway.
1108
1144
 
1109
- INFO: Nearly every tangible object in Jax has an internal camera. This tracks its position as well as its orientation. Models, light sources, anything that can be added to the world can be positioned and oriented in exactly the same way.
1145
+ INFO: Nearly every tangible object in Jax has an internal camera. This tracks its position as well as its orientation. Models, light sources, anything that can be added to the world can be positioned and oriented in exactly the same way. In addition, since each Camera tracks its own frustum, (you don't need to know what this is right now), each object can "see" the other objects in the scene. This is very useful for AI programming.
1146
+
1147
+ !images/getting_started/dungeon-textured-lighting.png(Dungeon with Texture and Lighting)!
1148
+
1110
1149
 
1111
1150
  h3. Finishing Touches
1112
1151
 
@@ -1166,4 +1205,6 @@ Finally, edit the +app/resources/materials/dungeon.yml+ file and set the path to
1166
1205
  # ...
1167
1206
  </yaml>
1168
1207
 
1169
- Believe it or not, you're done setting up normal mapping! We've already got all of our lights, meshes and whatnot in place, so all you have to do now is reload your application to see the normal map in action.
1208
+ You're done setting up normal mapping! We've already got all of our lights, meshes and whatnot in place, so all you have to do now is reload your application to see the normal map in action.
1209
+
1210
+ !images/getting_started/dungeon-normal-map.png(Dungeon with Normal Mapping)!