rbglox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ THE MIT LICENSE
2
+
3
+ Copyright (c) 2011, Mihail Szabolcs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the 'Software'), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,184 @@
1
+ rbGLox
2
+ ======
3
+ rbGLox is a small wrapper over the ruby-opengl, ruby-glfw family by abstracting
4
+ and providing some high-level interfaces for things like "Textures",
5
+ "GLSL Shaders", basic "Geometry" and others.
6
+
7
+ It's ideal for rapid prototyping new and interesting ideas.
8
+
9
+ rbGLox is the sister project of [pyGLox](http://github.com/icebreaker/pyGLox).
10
+
11
+ Dependencies
12
+ ------------
13
+ * [ruby-opengl](https://rubygems.org/gems/ruby-opengl)
14
+ * [ruby-glfw](https://rubygems.org/gems/ruby-glfw)
15
+ * [directory-watcher](https://rubygems.org/gems/directory_watcher)
16
+
17
+ Getting Started
18
+ ---------------
19
+
20
+ ### Install
21
+
22
+ gem install rbglox
23
+
24
+ ### Library
25
+
26
+ Using rbGLox as a library is a very easy :)
27
+
28
+ ```ruby
29
+ require 'rbglox'
30
+ class DemoApp < RBGLox::App
31
+ def init
32
+ @texture = RBGLox::Texture.new 'mosaic.tga'
33
+ @r = 0.0
34
+ @cube = RBGLox::MeshCube.new
35
+ end
36
+ def update
37
+ @r += 0.1
38
+ end
39
+ def draw
40
+ glTranslatef 0.0,0.0,-6.0
41
+ glRotatef @r, 1.0, 1.0, 1.0
42
+
43
+ @texture.bind
44
+ @cube.draw
45
+ @texture.release
46
+ end
47
+ def shutdown
48
+ @texture.free
49
+ @cube.free
50
+ end
51
+ end
52
+ ```
53
+
54
+ Now let's fire this up :)
55
+
56
+ ```ruby
57
+ DemoApp.new do |app|
58
+ app.title = 'DemoApp'
59
+ app.exec
60
+ end
61
+ ```
62
+
63
+ Additional methods you can override:
64
+
65
+ ```ruby
66
+ resize(h, w)
67
+ begin_frame
68
+ end_frame
69
+ reload(event)
70
+ ```
71
+
72
+ #### Semi-automatic resource re-loading
73
+
74
+ ```ruby
75
+ DemoApp.new do |app|
76
+ app.watch = 'data/'
77
+ app.title = 'DemoApp'
78
+ app.exec
79
+ end
80
+ ```
81
+ If the `watch` variable is not `nil` then the given directory will be watched
82
+ for any changes. (i.e file modified, file created, etc)
83
+
84
+ Every time a change is detected, the `reload(event)` method is called and you can
85
+ reload your resources.
86
+
87
+ The included `RBGLox::Texture` and `RBGLox::Shader` classes have a `reload` method
88
+ which facilitates this as illustrated in the example below.
89
+
90
+ ```ruby
91
+ ...
92
+ def reload(event)
93
+ if event.type == :modified
94
+ texture1.reload if event.path =~ /myawesometexture.tga$/
95
+ shader.reload if event.path =~ /myshader.glsl$/
96
+ ...
97
+ end
98
+ ...
99
+ end
100
+ ...
101
+ ```
102
+
103
+ ### Executable
104
+
105
+ It is also possible to use rbGLox as a cheap & rudimentary "GLSL" shader editor.
106
+
107
+ In order to create a new project do the following:
108
+
109
+ mkdir glsl-demo
110
+ cd glsl-demo
111
+ rbglox --init
112
+
113
+ This will create an empty project with one shader and one texture.
114
+
115
+ To launch "editor" just type `rbglox` in the current directory and there you go.
116
+
117
+ #### Watcher
118
+
119
+ All the resources in the current directory are "watched" for changes and will be
120
+ reloaded automatically when a change is detected.
121
+
122
+ So, if you edit the shaders or the textures they will be reloaded for you without
123
+ restarting the "editor".
124
+
125
+ #### Shaders
126
+
127
+ The shader file has the following format:
128
+
129
+ [vertex]
130
+ ...
131
+ [end]
132
+
133
+ [fragment]
134
+ ...
135
+ [end]
136
+
137
+ [uniforms]
138
+ ...
139
+ [end]
140
+
141
+ Please consult the generated `default shader` when you start a "new project" for
142
+ more details.
143
+
144
+ The shader must be named `shader.glsl` in order to be used and loaded.
145
+
146
+
147
+ #### Textures
148
+
149
+ Only textures in the TGA format are supported and they are going to be loaded
150
+ in alphabetical order. If there are more than 4 textures, only the first 4
151
+ will be loaded and assigned to the first 4 available texture units.
152
+
153
+ The textures must be named in the following format: `textureN.tga` where `N`
154
+ is a number ranging from 1 to 4.
155
+
156
+ #### Models (a.k.a Meshes)
157
+
158
+ You can choose between a Quad, a Cube (a.k.a Box) and a Teapot. The default is
159
+ the Teapot.
160
+
161
+ rbglox --model teapot
162
+
163
+ #### Controls
164
+
165
+ * Hold down the left mouse button and move the mouse in order to rotate the model.
166
+ * Use the mouse wheel to zoom in / zoom out the model.
167
+
168
+ rbMedia
169
+ -------
170
+ The bundled texture is from [lovetextures.com](http://lovetextures.com) .
171
+
172
+ Contribute
173
+ ----------
174
+ * Fork the project.
175
+ * Make your feature addition or bug fix.
176
+ * Send me a pull request. Bonus points for topic branches.
177
+ * Do **not** bump the version number.
178
+
179
+ License
180
+ -------
181
+ Copyright (c) 2011, Mihail Szabolcs
182
+
183
+ rbGLox is provided as-is under the **MIT** license. For more information
184
+ see *LICENSE* .
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'rbglox'
6
+ require 'optparse'
7
+ require 'ftools'
8
+
9
+ help = <<HELP
10
+ RBGLox v#{RBGLox::VERSION}
11
+
12
+ usage: rbglox [options]
13
+
14
+ Examples:
15
+ rbglox --init
16
+ rbglox --model=teapot
17
+ rbglox --title="My GLSL Demo"
18
+
19
+ Models:
20
+ quad, cube, teapot
21
+
22
+ Options:
23
+ HELP
24
+
25
+ options =
26
+ {
27
+ 'model' => 'teapot',
28
+ 'title' => "RBGLox v#{RBGLox::VERSION}"
29
+ }
30
+ opts = OptionParser.new do |opts|
31
+ opts.banner = help
32
+
33
+ opts.on('--init', 'create an empty project in the current directory') do
34
+ options['init'] = true
35
+ end
36
+
37
+ opts.on('--model [model]', 'specify sample model') do |model|
38
+ if ['quad', 'cube', 'box', 'teapot'].include? model
39
+ options['model'] = model
40
+ end
41
+ end
42
+
43
+ opts.on('--title [title]', 'specify window title') do |title|
44
+ options['title'] = title
45
+ end
46
+
47
+ opts.on('--version', 'show version information') do
48
+ puts RBGLox::VERSION
49
+ exit 0
50
+ end
51
+ end
52
+
53
+ begin
54
+ opts.parse!
55
+ rescue OptionParser::InvalidOption => e
56
+ puts e.message
57
+ exit 1
58
+ end
59
+
60
+ def init(src, dst)
61
+ puts 'Copying shader ...'
62
+ File.copy(File.join(src, 'res/shader.glsl'), File.join(dst, 'shader.glsl'))
63
+ puts 'Copying texture ...'
64
+ File.copy(File.join(src, 'res/texture.tga'), File.join(dst, 'texture1.tga'))
65
+ puts 'Now run `rbglox` and enjoy :)'
66
+ 0
67
+ end
68
+
69
+ exit init(File.dirname(File.dirname(__FILE__)), Dir.getwd) unless options['init'].nil?
70
+
71
+ unless File.exists?(File.join(Dir.getwd, 'shader.glsl'))
72
+ puts 'Error. No `shader.glsl` found in the current directory.'
73
+ exit 1
74
+ end
75
+
76
+ unless File.exists?(File.join(Dir.getwd, 'texture1.tga'))
77
+ puts 'Warning. No `texture1.tga` found in the current directory.'
78
+ end
79
+
80
+ ShaderApp.new do |app|
81
+ app.title = options['title']
82
+ app.model = options['model']
83
+ app.watch = Dir.getwd
84
+ app.exec
85
+ end
@@ -0,0 +1,126 @@
1
+ require 'gl'
2
+ require 'glu'
3
+ require 'glut'
4
+ require 'glfw'
5
+ require 'directory_watcher'
6
+
7
+ module RBGLox
8
+ class RBGLoxException < StandardError; end
9
+ end
10
+
11
+ require 'rbglox/version'
12
+ require 'rbglox/window'
13
+ require 'rbglox/resource'
14
+ require 'rbglox/texture'
15
+ require 'rbglox/shader'
16
+ require 'rbglox/mesh'
17
+ require 'rbglox/meshquad'
18
+ require 'rbglox/meshcube'
19
+ require 'rbglox/app'
20
+
21
+ class ShaderApp < RBGLox::App
22
+ attr_accessor :model
23
+
24
+ def init
25
+ @textures = []
26
+ (1..4).each do |i|
27
+ filename = File.join watch, "texture#{i}.tga"
28
+ @textures << RBGLox::Texture.new(filename) if File.exists? filename
29
+ end
30
+
31
+ @shader = RBGLox::Shader.new File.join watch, "shader.glsl"
32
+
33
+ @z = -6.0
34
+ if model == 'quad'
35
+ @model = RBGLox::MeshQuad.new
36
+ elsif ['cube', 'box'].include? model
37
+ @model = RBGLox::MeshCube.new
38
+ else
39
+ @model = nil
40
+ @z = -30.0
41
+ end
42
+
43
+ @lastX = 0
44
+ @lastY = 0
45
+ @lastM = 0
46
+
47
+ @rotX = 0.0
48
+ @rotY = 0.0
49
+ @rotZ = 0.0
50
+ end
51
+
52
+ def update
53
+ currM = mouse_wheel?
54
+
55
+ if currM != 0
56
+ @z -= (@lastM - currM)
57
+ @lastM = currM
58
+ end
59
+
60
+ if mouse_left?
61
+ currX, currY = mouse_pos?
62
+
63
+ if @lastX > 0 and @lastY > 0
64
+ @rotX += (currY - @lastY)
65
+ @rotY += (currX - @lastX)
66
+ end
67
+
68
+ @lastX = currX
69
+ @lastY = currY
70
+ else
71
+ @lastX = 0
72
+ @lastY = 0
73
+ end
74
+
75
+ end
76
+
77
+ def draw
78
+ glTranslatef(0,0, @z)
79
+ glRotatef(@rotX, 1.0, 0.0, 0.0)
80
+ glRotatef(@rotY, 0.0, 1.0, 0.0)
81
+ glRotatef(@rotZ, 0.0, 0.0, 1.0)
82
+
83
+ @textures.each_with_index do |texture, i|
84
+ texture.bind i
85
+ end
86
+
87
+ @shader.bind
88
+ @shader['time'] = time.to_f
89
+
90
+ if @model.nil?
91
+ glutSolidTeapot(8.0)
92
+ else
93
+ @model.draw
94
+ end
95
+
96
+ @shader.release
97
+
98
+ @textures.each_with_index do |texture, i|
99
+ texture.release i
100
+ end
101
+ end
102
+
103
+ def shutdown
104
+ @textures.each do |texture|
105
+ texture.free
106
+ end
107
+ @shader.free
108
+ @model.free unless @model.nil?
109
+ end
110
+
111
+ def reload(event)
112
+ if event.type == :modified
113
+ puts "reloading #{event.path} ..."
114
+ if event.path =~ /\.glsl$/i
115
+ @shader.reload
116
+ elsif event.path =~ /\.tga$/i
117
+ @textures.each_with_index do |texture, i|
118
+ if texture.filename == event.path
119
+ texture.reload i
120
+ break
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,9 @@
1
+ # Semi-abstract Application Class
2
+ class RBGLox::App < RBGLox::Window
3
+ # Constructor
4
+ def initialize
5
+ super
6
+ yield self
7
+ end
8
+ end
9
+
@@ -0,0 +1,36 @@
1
+ # Semi-abstract Mesh Class
2
+ class RBGLox::Mesh < RBGLox::Resource
3
+ include Gl
4
+
5
+ # Constructor
6
+ def initialize(verts, texs, norms, tris)
7
+ @id = glGenLists 1
8
+
9
+ glNewList id, GL_COMPILE
10
+ glPushClientAttrib GL_CLIENT_VERTEX_ARRAY_BIT
11
+ glEnableClientState GL_VERTEX_ARRAY
12
+ glEnableClientState GL_TEXTURE_COORD_ARRAY
13
+ glEnableClientState GL_NORMAL_ARRAY
14
+ glVertexPointer 3, GL_FLOAT, 0, verts
15
+ glNormalPointer GL_FLOAT, 0, norms
16
+ glTexCoordPointer 2, GL_FLOAT, 0, texs
17
+ glDrawElements GL_TRIANGLES, tris.size, GL_UNSIGNED_INT, tris
18
+ glPopClientAttrib
19
+ glEndList
20
+ end
21
+
22
+ # Draw the mesh by calling the internal display list
23
+ def draw
24
+ glCallList id
25
+ end
26
+
27
+ # Reload the mesh
28
+ def reload
29
+ # do nothing
30
+ end
31
+
32
+ # Free the mesh by destroying the internal display list
33
+ def free
34
+ glDeleteLists id, 1
35
+ end
36
+ end
@@ -0,0 +1,99 @@
1
+ # Cube Mesh Class
2
+ class RBGLox::MeshCube < RBGLox::Mesh
3
+ # Constructor
4
+ def initialize(x=1.0, y=1.0, z=1.0, tx=0.0, ty=0.0, tz=0.0)
5
+ verts = [
6
+ -x + tx, -y + ty, -z + tz,
7
+ x + tx, -y + ty, -z + tz,
8
+ x + tx, y + ty, -z + tz,
9
+ -x + tx, y + ty, -z + tz,
10
+ -x + tx, -y + ty, z + tz,
11
+ -x + tx, y + ty, z + tz,
12
+ x + tx, y + ty, z + tz,
13
+ x + tx, -y + ty, z + tz,
14
+ -x + tx, -y + ty, -z + tz,
15
+ -x + tx, y + ty, -z + tz,
16
+ -x + tx, y + ty, z + tz,
17
+ -x + tx, -y + ty, z + tz,
18
+ x + tx, -y + ty, -z + tz,
19
+ x + tx, -y + ty, z + tz,
20
+ x + tx, y + ty, z + tz,
21
+ x + tx, y + ty, -z + tz,
22
+ -x + tx, y + ty, -z + tz,
23
+ x + tx, y + ty, -z + tz,
24
+ x + tx, y + ty, z + tz,
25
+ -x + tx, y + ty, z + tz,
26
+ -x + tx, -y + ty, -z + tz,
27
+ -x + tx, -y + ty, z + tz,
28
+ x + tx, -y + ty, z + tz,
29
+ x + tx, -y + ty, -z + tz]
30
+
31
+ norms = [
32
+ 0, 0, -1,
33
+ 0, 0, -1,
34
+ 0, 0, -1,
35
+ 0, 0, -1,
36
+ 0, 0, 1,
37
+ 0, 0, 1,
38
+ 0, 0, 1,
39
+ 0, 0, 1,
40
+ -1, 0, 0,
41
+ -1, 0, 0,
42
+ -1, 0, 0,
43
+ -1, 0, 0,
44
+ 1, 0, 0,
45
+ 1, 0, 0,
46
+ 1, 0, 0,
47
+ 1, 0, 0,
48
+ 0, 1, 0,
49
+ 0, 1, 0,
50
+ 0, 1, 0,
51
+ 0, 1, 0,
52
+ 0, -1, 0,
53
+ 0, -1, 0,
54
+ 0, -1, 0,
55
+ 0, -1, 0 ]
56
+
57
+ texs = [
58
+ 0, 0, # 0
59
+ 1, 0, # 1
60
+ 1, 1, # 2
61
+ 0, 1, # 3
62
+ 1, 0, # 4
63
+ 1, 1, # 5
64
+ 0, 1, # 6
65
+ 0, 0, # 7
66
+ 1, 0, # 8
67
+ 1, 1, # 9
68
+ 0, 1, # 10
69
+ 0, 0, # 11
70
+ 0, 0, # 12
71
+ 1, 0, # 13
72
+ 1, 1, # 14
73
+ 0, 1, # 15
74
+ 0, 0, # 16
75
+ 1, 0, # 17
76
+ 1, 1, # 18
77
+ 0, 1, # 19
78
+ 0, 1, # 20
79
+ 0, 0, # 21
80
+ 1, 0, # 22
81
+ 1, 1 ] # 23
82
+
83
+ tris = [
84
+ 0, 2, 1,
85
+ 0, 3, 2,
86
+ 4, 6, 5,
87
+ 4, 7, 6,
88
+ 8, 10, 9,
89
+ 8, 11, 10,
90
+ 12, 14, 13,
91
+ 12, 15, 14,
92
+ 16, 18, 17,
93
+ 16, 19, 18,
94
+ 20, 22, 21,
95
+ 20, 23, 22 ]
96
+
97
+ super verts, texs, norms, tris
98
+ end
99
+ end
@@ -0,0 +1,29 @@
1
+ # Quad Mesh Class
2
+ class RBGLox::MeshQuad < RBGLox::Mesh
3
+ # Constructor
4
+ def initialize(x=1.0, y=1.0)
5
+ verts = [
6
+ -x, -y, 0.0,
7
+ x, -y, 0.0,
8
+ x, y, 0.0,
9
+ -x, y, 0.0 ]
10
+
11
+ texs = [
12
+ 0.0, 0.0,
13
+ 1.0, 0.0,
14
+ 1.0, 1.0,
15
+ 0.0, 1.0 ]
16
+
17
+ norms = [
18
+ 0.0, 0.0, 1.0,
19
+ 0.0, 0.0, 1.0,
20
+ 0.0, 0.0, 1.0,
21
+ 0.0, 0.0, 1.0 ]
22
+
23
+ tris = [
24
+ 3, 2, 1,
25
+ 3, 1, 0 ]
26
+
27
+ super verts, texs, norms, tris
28
+ end
29
+ end
@@ -0,0 +1,14 @@
1
+ # Abstract Resource Class
2
+ class RBGLox::Resource
3
+ attr_reader :id
4
+
5
+ # Reload resource
6
+ def reload
7
+ raise NotImplementedError
8
+ end
9
+
10
+ # Free resource
11
+ def free
12
+ raise NotImplementedError
13
+ end
14
+ end
@@ -0,0 +1,115 @@
1
+ # GLSL Shader Class
2
+ class RBGLox::Shader < RBGLox::Resource
3
+ include Gl
4
+
5
+ attr_reader :filename, :vertex, :fragment, :uniforms
6
+
7
+ # Constructor
8
+ def initialize(filename)
9
+ @filename = filename
10
+ @id = glCreateProgram
11
+
12
+ @vertex = glCreateShader GL_VERTEX_SHADER
13
+ glAttachShader id, vertex
14
+
15
+ @fragment = glCreateShader GL_FRAGMENT_SHADER
16
+ glAttachShader id, fragment
17
+
18
+ @uniforms = []
19
+
20
+ reload
21
+ end
22
+
23
+ # Set internal GLSL uniforms
24
+ def []=(name, value)
25
+ loc = glGetUniformLocation id, name
26
+ if value.is_a? Float
27
+ glUniform1f loc, value
28
+ elsif value.is_a? Integer
29
+ glUniform1i loc, value
30
+ elsif value.is_a? Array
31
+ l = value.size
32
+ if l == 2
33
+ glUniform2fv loc, value
34
+ elsif l == 3:
35
+ glUniform3fv loc, value
36
+ elsif l == 4:
37
+ glUniform4fv loc, value
38
+ end
39
+ else
40
+ raise TypeError.new('Uniform type not supported')
41
+ end
42
+ end
43
+
44
+ # Bind the Shader
45
+ def bind
46
+ glUseProgram id
47
+
48
+ uniforms.each do |k, v|
49
+ self[k] = v
50
+ end
51
+ end
52
+
53
+ # Release the Shader
54
+ def release
55
+ glUseProgram 0
56
+ end
57
+
58
+ # Reload the Shader
59
+ def reload
60
+ content = File.read filename
61
+ vert, frag, unis = parse content
62
+
63
+ glShaderSource vertex, vert
64
+ glCompileShader vertex
65
+ log = glGetShaderInfoLog vertex
66
+ puts log
67
+
68
+ return if log =~ /error/i
69
+
70
+ glShaderSource fragment, frag
71
+ glCompileShader fragment
72
+ log = glGetShaderInfoLog fragment
73
+ puts log
74
+
75
+ return if log =~ /error/i
76
+
77
+ glLinkProgram id
78
+ log = glGetProgramInfoLog id
79
+ puts log
80
+
81
+ return if log =~ /error/i
82
+
83
+ @uniforms = unis
84
+ end
85
+
86
+ # Free the Shader
87
+ def free
88
+ glDetachShader id, vertex
89
+ glDeleteShader vertex
90
+
91
+ glDetachShader id, fragment
92
+ glDeleteShader fragment
93
+
94
+ glDeleteProgram id
95
+ end
96
+
97
+ protected
98
+
99
+ # Parse the Shader file and extract the Vertex and Fragment shaders
100
+ def parse(content)
101
+ source = []
102
+
103
+ matches = content.scan(/\[(vertex|fragment|uniforms)\]\s?(.*?\s?)\s?\[end\]/m)
104
+ matches.each do |m|
105
+ if ["vertex", "fragment"].include?(m[0])
106
+ source.push(m[1])
107
+ elsif m[0] == "uniforms"
108
+ source.push(YAML.load(m[1]))
109
+ end
110
+ end
111
+
112
+ source
113
+ end
114
+
115
+ end
@@ -0,0 +1,52 @@
1
+ # Texture Class
2
+ class RBGLox::Texture < RBGLox::Resource
3
+ include Glfw
4
+ include Gl
5
+
6
+ attr_accessor :filename, :mipmaps
7
+
8
+ # Constructor
9
+ def initialize(filename, mipmaps=false)
10
+ @filename = filename
11
+ @mipmaps = mipmaps
12
+ @id = glGenTextures(1)[0]
13
+
14
+ reload
15
+ end
16
+
17
+ # Bind the Texture
18
+ def bind(unit=0)
19
+ glActiveTexture(GL_TEXTURE0 + unit)
20
+ glBindTexture GL_TEXTURE_2D, id
21
+ end
22
+
23
+ # Release the Texture
24
+ def release(unit=0)
25
+ glActiveTexture(GL_TEXTURE0 + unit)
26
+ glBindTexture GL_TEXTURE_2D, 0
27
+ end
28
+
29
+ # Reload the Texture
30
+ def reload(unit=0)
31
+ bind unit
32
+
33
+ glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE
34
+ glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE
35
+ glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR
36
+ glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR
37
+
38
+ if mipmaps:
39
+ glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST
40
+ glfwLoadTexture2D filename, GLFW_BUILD_MIPMAPS_BIT
41
+ else
42
+ glfwLoadTexture2D filename, 0
43
+ end
44
+
45
+ release unit
46
+ end
47
+
48
+ # Free the Texture
49
+ def free
50
+ glDeleteTextures [id]
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module RBGLox
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,172 @@
1
+ # Semi-abstract Window class
2
+ class RBGLox::Window
3
+ include Glfw
4
+ include Gl
5
+ include Glu
6
+ include Glut
7
+
8
+ attr_accessor :title, :width, :height, :multisample, :vsync, :watch
9
+
10
+ # Constructor
11
+ def initialize
12
+ @title = 'rbGLox'
13
+ @width = 640
14
+ @height= 480
15
+ @multisample = 0
16
+ @vsync = 0
17
+ @watch = nil
18
+ end
19
+
20
+ # Closes the currently active open window
21
+ def close
22
+ glfwCloseWindow
23
+ end
24
+
25
+ # Returns TRUE if the given key is PRESSED, otherwise FALSE
26
+ def key?(key)
27
+ glfwGetKey(key) == GLFW_PRESS
28
+ end
29
+
30
+ # Returns TRUE if the given mouse button is PRESSED, otherwise FALSE
31
+ def mouse?(button = GLFW_MOUSE_BUTTON_LEFT)
32
+ glfwGetMouseButton(button) == GLFW_PRESS
33
+ end
34
+
35
+ # Return TRUE if the left mouse button is PRESSED, otherwise FALSE
36
+ def mouse_left?
37
+ mouse?
38
+ end
39
+
40
+ # Return TRUE if the right mouse button is PRESSED, otherwise FALSE
41
+ def mouse_right?
42
+ mouse? GLFW_MOUSE_BUTTON_RIGHT
43
+ end
44
+
45
+ # Returns the current mouse position (tuple)
46
+ def mouse_pos?
47
+ glfwGetMousePos
48
+ end
49
+
50
+ # Returns the current mouse wheel delta position
51
+ def mouse_wheel?
52
+ glfwGetMouseWheel
53
+ end
54
+
55
+ # Returns the current tick count
56
+ def time
57
+ glfwGetTime
58
+ end
59
+
60
+ # Opens the window and fires up the event loop
61
+ def exec
62
+ glutInit
63
+
64
+ glfwOpenWindowHint GLFW_WINDOW_NO_RESIZE, true
65
+ #glfwOpenWindowHint GLFW_FSAA_SAMPLE, multisample
66
+
67
+ glfwOpenWindow width, height, 0, 0, 0, 0, 32, 0, GLFW_WINDOW
68
+
69
+ glfwSetWindowPos 0, 0
70
+ glfwSetWindowTitle title
71
+ glfwEnable GLFW_KEY_REPEAT
72
+ glfwSwapInterval vsync
73
+
74
+ glfwSetWindowSizeCallback lambda { |w, h| resize(w, h) }
75
+
76
+ trap('INT') do
77
+ glfwCloseWindow
78
+ end
79
+
80
+ unless watch.nil?
81
+ puts "Watching #{watch} for changes ..."
82
+ dw = DirectoryWatcher.new watch, :glob => "**/*", :pre_load => true, :interval => 1
83
+ dw.add_observer do |*args|
84
+ args.each do |event|
85
+ reload event
86
+ end
87
+ end
88
+ dw.start
89
+ end
90
+
91
+ glClearColor 0.2, 0.2, 0.2, 1
92
+ glClearDepth 1.0
93
+
94
+ glEnable GL_DEPTH_TEST
95
+ glDepthFunc GL_LEQUAL
96
+
97
+ glShadeModel GL_SMOOTH
98
+ glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST
99
+
100
+ glEnable GL_TEXTURE_2D
101
+ glEnable GL_COLOR_MATERIAL
102
+ glEnable GL_NORMALIZE
103
+
104
+ puts 'init'
105
+ init
106
+
107
+ while true
108
+ break unless glfwGetWindowParam GLFW_OPENED
109
+ break if key? GLFW_KEY_ESC
110
+
111
+ update
112
+
113
+ begin_frame
114
+ draw
115
+ end_frame
116
+ end
117
+
118
+ unless watch.nil?
119
+ dw.stop
120
+ end
121
+
122
+ shutdown
123
+ puts 'shutdown'
124
+ end
125
+
126
+ # User defined initializations
127
+ def init
128
+ end
129
+
130
+ # User defined shutdown
131
+ def shutdown
132
+ end
133
+
134
+ # User defined window resize, sets up viewport and perspective projection
135
+ def resize(w, h)
136
+ glViewport 0, 0, w, h
137
+
138
+ glMatrixMode GL_PROJECTION
139
+ glLoadIdentity
140
+
141
+ gluPerspective 45.0, w.to_f/h.to_f, 0.1, 1000.0
142
+
143
+ glMatrixMode GL_MODELVIEW
144
+ glLoadIdentity
145
+ end
146
+
147
+ # User defined method called when entering a frame
148
+ def begin_frame
149
+ glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
150
+ glLoadIdentity
151
+ end
152
+
153
+ # User defined method called when leaving the frame
154
+ def end_frame
155
+ glfwSwapBuffers
156
+ end
157
+
158
+ # User defined draw method
159
+ def draw
160
+ raise NotImplementedError
161
+ end
162
+
163
+ # User defined update method
164
+ def update
165
+ # empty
166
+ end
167
+
168
+ # User defined reload event method
169
+ def reload(event)
170
+ # empty
171
+ end
172
+ end
@@ -0,0 +1,35 @@
1
+ [vertex]
2
+ uniform float time;
3
+
4
+ void main()
5
+ {
6
+ gl_FrontColor = gl_Color;
7
+ gl_TexCoord[0] = gl_MultiTexCoord0;
8
+ gl_Position = ftransform();
9
+ }
10
+ [end]
11
+
12
+ [fragment]
13
+ uniform float time;
14
+ uniform float offset;
15
+ uniform vec2 discardOffset;
16
+ uniform sampler2D tex0;
17
+ uniform sampler2D tex1;
18
+ uniform sampler2D tex2;
19
+ uniform sampler2D tex3;
20
+
21
+ void main()
22
+ {
23
+ vec2 st = gl_TexCoord[0].st;
24
+
25
+ if(st.t < discardOffset[0] || st.s < discardOffset[1])
26
+ discard;
27
+
28
+ gl_FragColor = texture2D(tex0, st * offset);
29
+ }
30
+ [end]
31
+
32
+ [uniforms]
33
+ discardOffset: [0.1, 0.1]
34
+ offset: 0.3
35
+ [end]
Binary file
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'rbglox'
4
+
5
+ class RBGLoxTest < Test::Unit::TestCase
6
+ def test_version
7
+ assert_equal RBGLox::VERSION, '0.1.0'
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbglox
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Mihail Szabolcs
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-06-19 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: ruby-opengl
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 237
30
+ segments:
31
+ - 0
32
+ - 60
33
+ - 1
34
+ version: 0.60.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: ruby-glfw
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 57
46
+ segments:
47
+ - 0
48
+ - 9
49
+ - 1
50
+ version: 0.9.1
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: directory_watcher
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 7
62
+ segments:
63
+ - 1
64
+ - 4
65
+ - 0
66
+ version: 1.4.0
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ description: rbGLox is a small wrapper over the ruby-opengl, ruby-glfw.
70
+ email:
71
+ - szaby@szabster.net
72
+ executables:
73
+ - rbglox
74
+ extensions: []
75
+
76
+ extra_rdoc_files:
77
+ - README.md
78
+ - LICENSE
79
+ files:
80
+ - lib/rbglox/window.rb
81
+ - lib/rbglox/texture.rb
82
+ - lib/rbglox/resource.rb
83
+ - lib/rbglox/app.rb
84
+ - lib/rbglox/mesh.rb
85
+ - lib/rbglox/meshcube.rb
86
+ - lib/rbglox/meshquad.rb
87
+ - lib/rbglox/shader.rb
88
+ - lib/rbglox/version.rb
89
+ - lib/rbglox.rb
90
+ - res/shader.glsl
91
+ - res/texture.tga
92
+ - README.md
93
+ - LICENSE
94
+ - test/test_rbglox.rb
95
+ - bin/rbglox
96
+ has_rdoc: true
97
+ homepage: http://github.com/icebreaker/rbglox
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options:
102
+ - --charset=UTF-8
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirements: []
124
+
125
+ rubyforge_project: rbglox
126
+ rubygems_version: 1.3.7
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: rbGLox is a small wrapper over the ruby-opengl, ruby-glfw family by abstracting and providing some high-level interfaces for things like "Textures", "GLSL Shaders", basic "Geometry" and others.
130
+ test_files:
131
+ - test/test_rbglox.rb