mittsu 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +18 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +1158 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +2 -1
  7. data/LICENSE.txt +1 -1
  8. data/README.md +173 -7
  9. data/circle.yml +20 -0
  10. data/install-glfw-3.1.2.sh +14 -0
  11. data/lib/mittsu.rb +0 -2
  12. data/lib/mittsu/extras/image_utils.rb +59 -55
  13. data/lib/mittsu/renderers/glfw_window.rb +17 -2
  14. data/lib/mittsu/renderers/opengl_renderer.rb +1 -1
  15. data/lib/mittsu/renderers/shaders/shader_lib.rb +4 -4
  16. data/lib/mittsu/version.rb +1 -1
  17. data/mittsu.gemspec +11 -5
  18. metadata +53 -71
  19. data/.travis.yml +0 -3
  20. data/examples/01_-_Default1noCulling.png +0 -0
  21. data/examples/01_scene_example.rb +0 -14
  22. data/examples/02_box_mesh_example.rb +0 -30
  23. data/examples/02_sphere_mesh_example.rb +0 -30
  24. data/examples/03_complex_object_example.rb +0 -52
  25. data/examples/04_ambient_light_example.rb +0 -33
  26. data/examples/04_dir_light_example.rb +0 -36
  27. data/examples/04_hemi_light_example.rb +0 -30
  28. data/examples/04_point_light_example.rb +0 -50
  29. data/examples/04_spot_light_example.rb +0 -44
  30. data/examples/05_earth_example.rb +0 -42
  31. data/examples/05_earth_moon_example.rb +0 -46
  32. data/examples/05_texture_example.rb +0 -32
  33. data/examples/06_cube_texture_example.rb +0 -36
  34. data/examples/06_skybox_example.rb +0 -60
  35. data/examples/07_earth_normal_example.rb +0 -36
  36. data/examples/08_shadow_example.rb +0 -87
  37. data/examples/09_line_example.rb +0 -52
  38. data/examples/10_obj_loader_example.rb +0 -68
  39. data/examples/11_character_input_example.rb +0 -18
  40. data/examples/11_continuous_keyboard_input_example.rb +0 -35
  41. data/examples/11_keyboard_input_example.rb +0 -43
  42. data/examples/12_mouse_click_example.rb +0 -38
  43. data/examples/12_mouse_motion_example.rb +0 -35
  44. data/examples/12_mouse_scroll_example.rb +0 -36
  45. data/examples/12_orbit_zoom_example.rb +0 -68
  46. data/examples/13_joystick_example.rb +0 -80
  47. data/examples/cubemap/tron_bk.png +0 -0
  48. data/examples/cubemap/tron_dn.png +0 -0
  49. data/examples/cubemap/tron_ft.png +0 -0
  50. data/examples/cubemap/tron_lf.png +0 -0
  51. data/examples/cubemap/tron_rt.png +0 -0
  52. data/examples/cubemap/tron_up.png +0 -0
  53. data/examples/earth.png +0 -0
  54. data/examples/earth_normal.png +0 -0
  55. data/examples/example_helper.rb +0 -2
  56. data/examples/male-02-1noCulling.png +0 -0
  57. data/examples/male02.mtl +0 -54
  58. data/examples/male02.obj +0 -13888
  59. data/examples/moon.png +0 -0
  60. data/examples/orig_02_-_Defaul1noCulling.png +0 -0
  61. data/examples/texture.png +0 -0
@@ -0,0 +1 @@
1
+ 2.0.0-p353
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in mittsu.gemspec
4
3
  gemspec
4
+
5
+ gem "codeclimate-test-reporter", group: :test, require: nil
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Daniel Smith
3
+ Copyright (c) 2015-2016 Daniel Smith
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,11 +1,27 @@
1
1
  # Mittsu
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mittsu`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Gem Version](https://badge.fury.io/rb/mittsu.svg)](https://badge.fury.io/rb/mittsu) [![Dependency Status](https://gemnasium.com/jellymann/mittsu.svg)](https://gemnasium.com/jellymann/mittsu) [![Circle CI](https://circleci.com/gh/jellymann/mittsu/tree/master.svg?style=shield)](https://circleci.com/gh/jellymann/mittsu/tree/master) [![Test Coverage](https://codeclimate.com/github/jellymann/mittsu/badges/coverage.svg)](https://codeclimate.com/github/jellymann/mittsu/coverage) [![Code Climate](https://codeclimate.com/github/jellymann/mittsu/badges/gpa.svg)](https://codeclimate.com/github/jellymann/mittsu)
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ 3D Graphics Library for Ruby
6
+
7
+ Mittsu makes 3D graphics easier by providing an abstraction over OpenGL, and is based heavily off of [THREE.js](http://threejs.org). No more weird pointers and wondering about the difference between a VAO and a VBO (besides the letter). Simply think of something awesome and make it!
6
8
 
7
9
  ## Installation
8
10
 
11
+ Install the prerequisites:
12
+
13
+ Mittsu depends on Ruby 2.x, OpenGL 3.3+, GLFW 3.1.x and ImageMagick 6.4.9+
14
+
15
+ ```bash
16
+ # OSX
17
+ $ brew intall glfw3 imagemagick
18
+
19
+ # Ubuntu
20
+ $ sudo apt-get install libglfw3-dev libmagickwand-dev
21
+ ```
22
+
23
+ **NOTE**: On Ubuntu, you may need to install `libgl1-mesa-dev` for the OpenGL dependency.
24
+
9
25
  Add this line to your application's Gemfile:
10
26
 
11
27
  ```ruby
@@ -22,18 +38,168 @@ Or install it yourself as:
22
38
 
23
39
  ## Usage
24
40
 
25
- TODO: Write usage instructions here
41
+ ### tl;dr
42
+
43
+ Copy-Paste and Run:
44
+
45
+ ```ruby
46
+ require 'mittsu'
47
+
48
+ SCREEN_WIDTH = 800
49
+ SCREEN_HEIGHT = 600
50
+ ASPECT = SCREEN_WIDTH.to_f / SCREEN_HEIGHT.to_f
26
51
 
27
- ## Development
52
+ renderer = Mittsu::OpenGLRenderer.new width: SCREEN_WIDTH, height: SCREEN_HEIGHT, title: 'Hello, World!'
53
+
54
+ scene = Mittsu::Scene.new
55
+
56
+ camera = Mittsu::PerspectiveCamera.new(75.0, ASPECT, 0.1, 1000.0)
57
+ camera.position.z = 5.0
58
+
59
+ box = Mittsu::Mesh.new(
60
+ Mittsu::BoxGeometry.new(1.0, 1.0, 1.0),
61
+ Mittsu::MeshBasicMaterial.new(color: 0x00ff00)
62
+ )
63
+
64
+ scene.add(box)
65
+
66
+ renderer.window.run do
67
+ box.rotation.x += 0.1
68
+ box.rotation.y += 0.1
69
+
70
+ renderer.render(scene, camera)
71
+ end
72
+ ```
73
+
74
+ ### Step by Step
75
+
76
+ First, we need to require Mittsu in order to use it:
77
+ ```ruby
78
+ require 'mittsu'
79
+ ```
28
80
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
81
+ Then, we'll define some constants to help us with setting up our 3D environment:
82
+ ```ruby
83
+ SCREEN_WIDTH = 800
84
+ SCREEN_HEIGHT = 600
85
+ ASPECT = SCREEN_WIDTH.to_f / SCREEN_HEIGHT.to_f
86
+ ```
87
+
88
+ The aspect ratio will be used for setting up the camera later.
89
+
90
+ Once we have all that we can create the canvas we will use to draw our graphics onto. In Mittsu this is called a renderer. It provides a window and an OpenGL context:
91
+
92
+ ```ruby
93
+ renderer = Mittsu::OpenGLRenderer.new width: SCREEN_WIDTH, height: SCREEN_HEIGHT, title: 'Hello, World!'
94
+ ```
95
+ This will give us an 800x600 window with the title `Hello, World!`.
96
+
97
+ Now that we have our canvas, let's start setting up the scene we wish to draw onto it:
98
+
99
+ ```ruby
100
+ scene = Mittsu::Scene.new
101
+ ```
102
+
103
+ A scene is like a stage where all our 3D objects live and animate.
104
+
105
+ We can't draw a 3D scene without knowing where we're looking:
106
+
107
+ ```ruby
108
+ camera = Mittsu::PerspectiveCamera.new(75.0, ASPECT, 0.1, 1000.0)
109
+ ```
110
+
111
+ This camera has a 75° field-of-view (FOV), the aspect ratio of the window (which we defined earlier), and shows everything between a distance of 0.1 to 1000.0 away from the camera.
112
+
113
+ The camera starts off at the origin `[0,0,0]` and faces the negative Z-axis. We'll position it somewhere along the positive Z-axis so that it is looking at the center of the scene from a short distance:
114
+
115
+ ```ruby
116
+ camera.position.z = 5.0
117
+ ```
30
118
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
119
+ Our scene isn't going to be very exciting if there is nothing in it, so we'll create a box:
120
+
121
+ ```ruby
122
+ box = Mittsu::Mesh.new(
123
+ Mittsu::BoxGeometry.new(1.0, 1.0, 1.0),
124
+ Mittsu::MeshBasicMaterial.new(color: 0x00ff00)
125
+ )
126
+ ```
127
+
128
+ A `Mesh` in Mittsu is the combination of a `Geometry` (the shape of the object) and a `Material` (the "look" of the object). Here we've created a 1x1x1 box that is colored green.
129
+
130
+ Box in hand, we make it part of our scene:
131
+
132
+ ```ruby
133
+ scene.add(box)
134
+ ```
135
+
136
+ Here comes the fun part... the render loop!
137
+
138
+ ```ruby
139
+ renderer.window.run do
140
+ ```
141
+
142
+ The given block is called every frame. This is where you can tell the renderer what scene to draw, and do any updates to the objects in your scene.
143
+
144
+ Just to make things a bit more interesting, we'll make the box rotate around its X and Y axes, so that it spins like crazy.
145
+
146
+ ```ruby
147
+ box.rotation.x += 0.1
148
+ box.rotation.y += 0.1
149
+ ```
150
+
151
+ Last but not least, we tell the renderer to draw our scene this frame, which will tell the graphics processor to draw our green box with its updated rotation.
152
+
153
+ ```ruby
154
+ renderer.render(scene, camera)
155
+ ```
156
+
157
+ Easy peasy! :)
158
+
159
+ ```ruby
160
+ end
161
+ ```
162
+
163
+
164
+ ### More Resources
165
+
166
+ Mittsu follows a similar structure to THREE.js, so you can generally use [the same documentation](http://threejs.org/docs/) for a description of the various classes and how they work.
167
+
168
+ If you just want to see what Mittsu can do and how to do it, take a peek inside the `examples` folder.
169
+
170
+ ## Where you can help
171
+
172
+ 1. Testing!
173
+
174
+ Currently the only unit tests are for most of the maths library, otherwise the library is tested by running the examples and checking that they look correct.
175
+
176
+ 2. Refactoring!
177
+
178
+ The code is unfortunately still a mess. Mittsu started out as a direct port of THREE.js, and JavaScript to Ruby is not an exact science.
179
+
180
+ 3. Find Bugs!
181
+
182
+ Mittsu is still very young, and there are plenty of small bugs and glitches that need to be ironed out. If you find a bug, create an issue so we can track it and squash it.
183
+
184
+ 4. Add all the features!
185
+
186
+ Some of the things I'd like to see ported from THREE.js include:
187
+
188
+ * Picking (clicking on 3D objects in a scene)
189
+ * Bone structure/animation (e.g. for character movements)
190
+ * Lens Flares! (for JJ Abrams)
191
+ * All the Extras and Helpers (who doesn't need extra help?)
192
+
193
+ 5. Write documentation!
194
+
195
+ You can use the same docs as THREE.js for now, but I would like to provide Mittsu-specific documentation so devs don't have to keep replacing `new THREE.Thing()` with `Mittsu::Thing.new`.
32
196
 
33
197
  ## Contributing
34
198
 
35
- 1. Fork it ( https://github.com/[my-github-username]/mittsu/fork )
199
+ 1. Fork it ( https://github.com/jellymann/mittsu/fork )
36
200
  2. Create your feature branch (`git checkout -b my-new-feature`)
37
201
  3. Commit your changes (`git commit -am 'Add some feature'`)
38
202
  4. Push to the branch (`git push origin my-new-feature`)
39
203
  5. Create a new Pull Request
204
+
205
+ Thank you for helping me help you help us all. ;)
@@ -0,0 +1,20 @@
1
+ ## Customize the test machine
2
+ machine:
3
+
4
+ # Version of ruby to use
5
+ ruby:
6
+ version:
7
+ 2.0.0
8
+
9
+ ## Customize dependencies
10
+ dependencies:
11
+ cache_directories:
12
+ - glfw-3.1.2
13
+ pre:
14
+ - sudo apt-get update; sudo apt-get install cmake xorg-dev libgl1-mesa-dev
15
+ - bash ./install-glfw-3.1.2.sh
16
+
17
+ test:
18
+ post:
19
+ - mkdir -p $CIRCLE_TEST_REPORTS/minitest/
20
+ - cp -r test/reports/*.xml $CIRCLE_TEST_REPORTS/minitest/
@@ -0,0 +1,14 @@
1
+ set -x
2
+ set -e
3
+ if [ ! -e glfw-3.1.2/include/GLFW/glfw3.h ]; then
4
+ wget https://github.com/glfw/glfw/releases/download/3.1.2/glfw-3.1.2.zip
5
+ unzip glfw-3.1.2.zip;
6
+ fi
7
+ cd glfw-3.1.2
8
+ if [ ! -e src/libglfw3.so ]; then
9
+ cmake -D BUILD_SHARED_LIBS=ON .
10
+ make;
11
+ fi
12
+ if [ ! -e /usr/local/lib/libglfw.so ]; then
13
+ sudo make install;
14
+ fi
@@ -1,5 +1,3 @@
1
- require "pry"
2
-
3
1
  require "mittsu/version"
4
2
  require "mittsu/math"
5
3
  require "mittsu/core"
@@ -1,80 +1,84 @@
1
1
  module Mittsu
2
2
  module ImageUtils
3
- def self.load_texture(url, mapping = Texture::DEFAULT_MAPPING)
4
- loader = ImageLoader.new
3
+ class << self
4
+ def load_texture(url, mapping = Texture::DEFAULT_MAPPING)
5
+ loader = ImageLoader.new
5
6
 
6
- Texture.new(nil, mapping).tap do |texture|
7
- image = loader.load(url, flip: true)
8
- texture.image = image
9
- texture.needs_update = true
7
+ Texture.new(nil, mapping).tap do |texture|
8
+ image = loader.load(url, flip: true)
9
+ texture.image = image
10
+ texture.needs_update = true
10
11
 
11
- texture.source_file = url
12
+ texture.source_file = url
13
+ end
12
14
  end
13
- end
14
15
 
15
- def self.load_texture_cube(array, mapping = Texture::DEFAULT_MAPPING)
16
- images = HashArray.new
16
+ def load_texture_cube(array, mapping = Texture::DEFAULT_MAPPING)
17
+ images = HashArray.new
17
18
 
18
- loader = ImageLoader.new
19
- CubeTexture.new(images, mapping).tap do |texture|
20
- loaded = 0
19
+ loader = ImageLoader.new
20
+ CubeTexture.new(images, mapping).tap do |texture|
21
+ loaded = 0
21
22
 
22
- array.length.times do |i|
23
- texture.images[i] = loader.load(array[i])
24
- loaded += 1
25
- if loaded == 6
26
- texture.needs_update = true
23
+ array.length.times do |i|
24
+ texture.images[i] = loader.load(array[i])
25
+ loaded += 1
26
+ if loaded == 6
27
+ texture.needs_update = true
28
+ end
27
29
  end
28
30
  end
29
31
  end
30
- end
31
32
 
32
- def self.get_normal_map(image, depth)
33
- # adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
33
+ def get_normal_map(image, depth)
34
+ # adapted from http://www.paulbrunt.co.uk/lab/heightnormal/
34
35
 
35
- # depth |= 1
36
- #
37
- # width = image.width
38
- # height = image.height
36
+ # depth |= 1
37
+ #
38
+ # width = image.width
39
+ # height = image.height
39
40
 
40
- # TODO: original version uses browser features ...
41
- end
41
+ # TODO: original version uses browser features ...
42
+ end
42
43
 
43
- def self.generate_data_texture(width, height, color)
44
- size = width * height
45
- data = Array.new(3 * size) # Uint8Array
44
+ def generate_data_texture(width, height, color)
45
+ size = width * height
46
+ data = Array.new(3 * size) # Uint8Array
46
47
 
47
- r = (color.r * 255).floor
48
- g = (color.g * 255).floor
49
- b = (color.b * 255).floor
48
+ r = (color.r * 255).floor
49
+ g = (color.g * 255).floor
50
+ b = (color.b * 255).floor
50
51
 
51
- size.times do |i|
52
- data[i * 3] = r
53
- data[i * 3 + 1] = g
54
- data[i * 3 + 2] = b
55
- end
52
+ size.times do |i|
53
+ data[i * 3] = r
54
+ data[i * 3 + 1] = g
55
+ data[i * 3 + 2] = b
56
+ end
56
57
 
57
- texture = DataTexture.new(data, width, height, RGBFormat)
58
- texture.needs_update = true
58
+ texture = DataTexture.new(data, width, height, RGBFormat)
59
+ texture.needs_update = true
59
60
 
60
- texture
61
- end
61
+ texture
62
+ end
62
63
 
63
- private_class_method def self.cross(a, b)
64
- [
65
- a[1] * b[2] - a[2] * b[1],
66
- a[2] * b[0] - a[0] * b[2],
67
- a[0] * b[1] - a[1] * b[0]
68
- ]
69
- end
64
+ private
70
65
 
71
- private_class_method def self.subtract(a, b)
72
- [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
73
- end
66
+ def cross(a, b)
67
+ [
68
+ a[1] * b[2] - a[2] * b[1],
69
+ a[2] * b[0] - a[0] * b[2],
70
+ a[0] * b[1] - a[1] * b[0]
71
+ ]
72
+ end
73
+
74
+ def subtract(a, b)
75
+ [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
76
+ end
74
77
 
75
- private_class_method def self.normalize(a)
76
- l = Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
77
- [a[0] / l, a[1] / l, a[2] / l]
78
+ def normalize(a)
79
+ l = Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2])
80
+ [a[0] / l, a[1] / l, a[2] / l]
81
+ end
78
82
  end
79
83
  end
80
84
  end
@@ -1,8 +1,20 @@
1
1
  require 'opengl'
2
2
  require 'glfw'
3
3
 
4
- path = `pkg-config glfw3 --libs-only-L`.chomp.strip[2..-1]
5
- GLFW.load_lib('libglfw3.dylib', path)
4
+ GLFW_LIB_EXT = OpenGL.get_platform == :OPENGL_PLATFORM_MACOSX ? 'dylib' : 'so'
5
+ GLFW_LIB = begin
6
+ "lib#{`pkg-config --libs-only-l glfw3`.gsub(/^-l/, '').chomp.strip}.#{GLFW_LIB_EXT}"
7
+ rescue
8
+ "libglfw.#{GLFW_LIB_EXT}"
9
+ end
10
+ GLFW_LIB_PATH = begin
11
+ s = `pkg-config glfw3 --libs-only-L`.gsub(/^-L/, '').chomp.strip
12
+ s.empty? ? nil : s
13
+ rescue
14
+ nil
15
+ end
16
+
17
+ GLFW.load_lib GLFW_LIB, GLFW_LIB_PATH
6
18
 
7
19
  include GLFW
8
20
 
@@ -22,6 +34,9 @@ module Mittsu
22
34
 
23
35
  @width, @height, @title = width, height, title
24
36
  @handle = glfwCreateWindow(@width, @height, @title, nil, nil)
37
+ if @handle.null?
38
+ raise "Unable to create window."
39
+ end
25
40
  glfwMakeContextCurrent @handle
26
41
  glfwSwapInterval 1
27
42
 
@@ -21,7 +21,7 @@ module Mittsu
21
21
  attr_accessor :auto_clear, :auto_clear_color, :auto_clear_depth, :auto_clear_stencil, :sort_objects, :gamma_factor, :gamma_input, :gamma_output, :shadow_map_enabled, :shadow_map_type, :shadow_map_cull_face, :shadow_map_debug, :shadow_map_cascade, :max_morph_targets, :max_morph_normals, :info, :pixel_ratio, :window, :width, :height, :state
22
22
 
23
23
  def initialize(parameters = {})
24
- puts "OpenGLRenderer #{REVISION}"
24
+ puts "OpenGLRenderer (Revision #{REVISION})"
25
25
 
26
26
  @pixel_ratio = 1.0
27
27