mittsu 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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