perlin 0.1.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/LICENSE +21 -0
- data/README.md +33 -0
- data/Rakefile +85 -0
- data/examples/chunk_in_2d.rb +22 -0
- data/examples/chunk_in_3d.rb +24 -0
- data/examples/index_in_2d.rb +23 -0
- data/examples/index_in_3d.rb +25 -0
- data/examples/ogl/README.md +3 -0
- data/examples/ogl/run.rb +200 -0
- data/ext/perlin/classic.c +160 -0
- data/ext/perlin/classic.h +24 -0
- data/ext/perlin/extconf.rb +15 -0
- data/ext/perlin/generator.c +292 -0
- data/ext/perlin/generator.h +35 -0
- data/ext/perlin/perlin.c +27 -0
- data/ext/perlin/perlin.h +20 -0
- data/ext/perlin/simplex.c +475 -0
- data/ext/perlin/simplex.h +196 -0
- data/lib/perlin.rb +13 -0
- data/lib/perlin/1.9/perlin.so +0 -0
- data/lib/perlin/generator.rb +161 -0
- data/lib/perlin/version.rb +5 -0
- metadata +128 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
0.1.0
|
2
|
+
-----
|
3
|
+
|
4
|
+
* Converted to gem (previously was just a .c file).
|
5
|
+
* Added 3D chunks.
|
6
|
+
* Optimised chunk operations.
|
7
|
+
* Added Generator#[x, y]
|
8
|
+
* Added Generator#[x, y, z]
|
9
|
+
* Added Generator#chunk x, y, size_x, size_y
|
10
|
+
* Added Generator#chunk x, y, z, size_x, size_y, size_z
|
11
|
+
* Added Generator#persistence, #seed and #octave accessors.
|
12
|
+
* Added Perlin's Simplex generation (much faster).
|
13
|
+
* A number of general fixes (added rspec tests).
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009 Brian Jones
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
Perlin
|
2
|
+
======
|
3
|
+
|
4
|
+
A Perlin noise implementation based off
|
5
|
+
<http://freespace.virgin.net/hugo.elias/models/m_perlin.htm>. Implemented as a Ruby C extension, it is considerably faster than the pure Ruby equivalent, [perlin_noise](https://github.com/junegunn/perlin_noise).
|
6
|
+
|
7
|
+
- Written by Brian 'bojo' Jones <mojobojo@gmail.com>
|
8
|
+
- Optimizations thanks to Camille Goudeseune, Univ of Illinois, <cog@illinois.edu>
|
9
|
+
- Made into gem and extended by Bil Bas (bil.bagpuss@gmail.com)
|
10
|
+
|
11
|
+
- [Simplex noise functions copyright (c) 2007-2012 Eliot Eshelman](http://www.6by9.net/b/2012/02/03/simplex-noise-for-c-and-python)
|
12
|
+
|
13
|
+
INSTALL
|
14
|
+
-------
|
15
|
+
|
16
|
+
$ gem install perlin
|
17
|
+
|
18
|
+
USAGE
|
19
|
+
-----
|
20
|
+
|
21
|
+
require 'perlin'
|
22
|
+
|
23
|
+
# Takes values seed, persistence, and octaves
|
24
|
+
noise = Perlin::Generator.new 123, 1.0, 1
|
25
|
+
|
26
|
+
# Returns a 'height' value for (x, y)
|
27
|
+
puts noise[10, 20] #=> 0.9004574418067932
|
28
|
+
|
29
|
+
# Returns a 2D array of 'heights' for a range (x, y, size_x, size_y, interval)
|
30
|
+
arr = noise.chunk 1, 1, 2, 3, 1
|
31
|
+
|
32
|
+
p arr #= > [[0.05753844603896141, -0.2208995521068573, 0.3973901569843292],
|
33
|
+
# [0.1383310854434967, -0.22248442471027374, 0.15600799024105072]]
|
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rake/extensiontask'
|
4
|
+
require 'yard'
|
5
|
+
require 'redcloth'
|
6
|
+
require 'launchy'
|
7
|
+
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'devkit' # only used on windows
|
11
|
+
rescue LoadError
|
12
|
+
end
|
13
|
+
|
14
|
+
require File.expand_path('../lib/perlin/version', __FILE__)
|
15
|
+
|
16
|
+
CLOBBER << "coverage"
|
17
|
+
|
18
|
+
# somewhere in your Rakefile, define your gem spec
|
19
|
+
spec = Gem::Specification.new do |s|
|
20
|
+
s.name = 'perlin'
|
21
|
+
s.version = Perlin::VERSION
|
22
|
+
s.date = Time.now.strftime '%Y-%m-%d'
|
23
|
+
s.authors = ["Brian 'bojo' Jones", 'Camille Goudeseune', 'Bil Bas']
|
24
|
+
|
25
|
+
s.summary = 'Perlin Noise C extension'
|
26
|
+
s.description = <<-END
|
27
|
+
#{s.summary}
|
28
|
+
|
29
|
+
A Perlin/Simplex noise implementation based of
|
30
|
+
<http://freespace.virgin.net/hugo.elias/models/m_perlin.htm>. Implemented as a Ruby C extension.
|
31
|
+
END
|
32
|
+
|
33
|
+
s.email = %w<mojobojo@gmail.com>
|
34
|
+
s.files = Dir.glob %w<CHANGELOG LICENSE Rakefile README.md lib/**/*.* lib ext/**/*.* examples/**/*.*>
|
35
|
+
s.homepage = 'https://github.com/boj/ruby-perlin'
|
36
|
+
s.licenses = %w<MIT>
|
37
|
+
s.extensions << 'ext/perlin/extconf.rb'
|
38
|
+
s.rubyforge_project = 'ruby-perlin'
|
39
|
+
s.test_files = []
|
40
|
+
s.has_rdoc = 'yard'
|
41
|
+
|
42
|
+
s.add_development_dependency 'rake-compile', '~> 0.8.1'
|
43
|
+
s.add_development_dependency 'simplecov', '~> 0.6.4'
|
44
|
+
s.add_development_dependency 'launchy', '~> 2.1.0'
|
45
|
+
end
|
46
|
+
|
47
|
+
Gem::PackageTask.new spec do
|
48
|
+
end
|
49
|
+
|
50
|
+
Rake::ExtensionTask.new 'perlin', spec do |ext|
|
51
|
+
RUBY_VERSION =~ /(\d+.\d+)/
|
52
|
+
ext.lib_dir = "lib/perlin/#{$1}"
|
53
|
+
end
|
54
|
+
|
55
|
+
YARD::Rake::YardocTask.new
|
56
|
+
|
57
|
+
task :default => :spec
|
58
|
+
task :spec => :compile
|
59
|
+
|
60
|
+
RSpec::Core::RakeTask.new do |t|
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Generate SimpleCov test coverage and open in your browser"
|
64
|
+
task :coverage do
|
65
|
+
rm_r "coverage" rescue nil
|
66
|
+
|
67
|
+
sh %q<ruby -rsimplecov -e "SimpleCov.command_name 'spec'; SimpleCov.start">
|
68
|
+
|
69
|
+
Launchy.open "coverage/index.html" rescue nil
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Open yard docs in browser"
|
73
|
+
task :browse_yard => :yard do
|
74
|
+
Launchy.open "doc/index.html" rescue nil
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "Create platform-specific compiled gem"
|
78
|
+
task :native_gem do
|
79
|
+
Rake::Task["native"].invoke "gem"
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "Run benchmarks"
|
83
|
+
task :bench => :compile do
|
84
|
+
require File.expand_path("../bench/benchmarks.rb", __FILE__)
|
85
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'perlin'
|
2
|
+
|
3
|
+
def print_data(seed, persistence, octave, size_x, size_y, interval)
|
4
|
+
noise = Perlin::Generator.new seed, persistence, octave
|
5
|
+
|
6
|
+
puts
|
7
|
+
|
8
|
+
data = noise.chunk 0, 0, size_x, size_y, interval
|
9
|
+
size_y.times do |y|
|
10
|
+
str = ''
|
11
|
+
|
12
|
+
size_x.times do |x|
|
13
|
+
str << "%7.2f" % data[x][y]
|
14
|
+
end
|
15
|
+
|
16
|
+
puts str
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
print_data 5, 1.0, 1, 10, 500, 1
|
21
|
+
|
22
|
+
puts "\nDone!"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'perlin'
|
2
|
+
|
3
|
+
def print_data(seed, persistence, octave, size_x, size_y, size_z, interval)
|
4
|
+
noise = Perlin::Generator.new seed, persistence, octave
|
5
|
+
|
6
|
+
puts
|
7
|
+
|
8
|
+
data = noise.chunk 0, 0, 0, size_x, size_y, size_z, interval
|
9
|
+
size_z.times do |z|
|
10
|
+
size_y.times do |y|
|
11
|
+
str = ''
|
12
|
+
|
13
|
+
size_x.times do |x|
|
14
|
+
str << "%7.2f" % data[x][y]
|
15
|
+
end
|
16
|
+
|
17
|
+
puts str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
print_data 5, 1.0, 1, 10, 500, 99, 1.9
|
23
|
+
|
24
|
+
puts "\nDone!"
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'perlin'
|
2
|
+
|
3
|
+
def print_data(seed, persistence, octave, size_x, size_y)
|
4
|
+
noise = Perlin::Generator.new seed, persistence, octave
|
5
|
+
|
6
|
+
puts
|
7
|
+
|
8
|
+
# Note that it would be significantly faster to use #chunk in this example.
|
9
|
+
size_y.times do |y|
|
10
|
+
str = ''
|
11
|
+
|
12
|
+
size_x.times do |x|
|
13
|
+
n = noise.run2d x, y
|
14
|
+
str << "%7.2f" % n
|
15
|
+
end
|
16
|
+
|
17
|
+
puts str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
print_data 5, 1.0, 1, 10, 500
|
22
|
+
|
23
|
+
puts "\nDone!"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'perlin'
|
2
|
+
|
3
|
+
def print_data(seed, persistence, octave, size_x, size_y, size_z)
|
4
|
+
noise = Perlin::Generator.new seed, persistence, octave
|
5
|
+
|
6
|
+
puts
|
7
|
+
|
8
|
+
# Note that it would be significantly faster to use #chunk in this example.
|
9
|
+
size_z.times do |z|
|
10
|
+
size_y.times do |y|
|
11
|
+
str = ''
|
12
|
+
|
13
|
+
size_x.times do |x|
|
14
|
+
n = noise.run3d x, y, z
|
15
|
+
str << "%7.2f" % n
|
16
|
+
end
|
17
|
+
|
18
|
+
puts str
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
print_data 5, 1.0, 1, 10, 200, 99
|
24
|
+
|
25
|
+
puts "\nDone!"
|
data/examples/ogl/run.rb
ADDED
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'perlin'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'fox16'
|
4
|
+
|
5
|
+
# Base framework borrowed from: http://www.fxruby.org/examples/gltest.rb
|
6
|
+
|
7
|
+
include Fox
|
8
|
+
|
9
|
+
class GLTestWindow < FXMainWindow
|
10
|
+
|
11
|
+
# How often our timer will fire (in milliseconds)
|
12
|
+
TIMER_INTERVAL = 100
|
13
|
+
|
14
|
+
def drawTerrain(width, length)
|
15
|
+
p = Perlin.new(@p_seed.to_s.to_i, @p_freq.to_s.to_f, @p_octave.to_s.to_i)
|
16
|
+
|
17
|
+
GL.Begin(GL::QUADS)
|
18
|
+
for x in 0..width
|
19
|
+
for y in 0..length
|
20
|
+
material = [rand, rand, rand]
|
21
|
+
GL.Material(GL::FRONT, GL::AMBIENT, material)
|
22
|
+
GL.Material(GL::FRONT, GL::DIFFUSE, material)
|
23
|
+
GL.Vertex(x, y, p.run(x, y))
|
24
|
+
GL.Vertex(x + 1, y, p.run(x + 1, y))
|
25
|
+
GL.Vertex(x + 1, y + 1, p.run(x + 1, y + 1))
|
26
|
+
GL.Vertex(x, y + 1, p.run(x, y + 1))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
GL.End()
|
30
|
+
end
|
31
|
+
|
32
|
+
# Draw the GL scene
|
33
|
+
def drawScene
|
34
|
+
lightPosition = [5.0, 5.0, 5.0, 1.0]
|
35
|
+
lightAmbient = [ 0.5, 0.5, 0.5, 1.0]
|
36
|
+
lightDiffuse = [ 0.9, 0.9, 0.9, 1.0]
|
37
|
+
|
38
|
+
width = @glcanvas.width.to_f
|
39
|
+
height = @glcanvas.height.to_f
|
40
|
+
aspect = width / height
|
41
|
+
|
42
|
+
# Make context current
|
43
|
+
@glcanvas.makeCurrent()
|
44
|
+
|
45
|
+
GL.Viewport(0, 0, @glcanvas.width, @glcanvas.height)
|
46
|
+
|
47
|
+
GL.ClearColor(0.0, 0.0, 0.0, 0.0)
|
48
|
+
GL.Clear(GL::COLOR_BUFFER_BIT|GL::DEPTH_BUFFER_BIT)
|
49
|
+
GL.Enable(GL::DEPTH_TEST)
|
50
|
+
|
51
|
+
GL.Disable(GL::DITHER)
|
52
|
+
|
53
|
+
GL.MatrixMode(GL::PROJECTION)
|
54
|
+
GL.LoadIdentity()
|
55
|
+
GLU.Perspective(90.0, aspect, 1.0, 100.0)
|
56
|
+
|
57
|
+
GL.MatrixMode(GL::MODELVIEW)
|
58
|
+
GL.LoadIdentity()
|
59
|
+
x = (@p_width.to_s.to_i / 2.0)
|
60
|
+
y = (@p_length.to_s.to_i / 2.0)
|
61
|
+
GLU.LookAt(5.0, 15.0, 5.0, x, y, 0.0, 0.0, -1.0, 0.0)
|
62
|
+
|
63
|
+
GL.ShadeModel(GL::SMOOTH)
|
64
|
+
GL.Light(GL::LIGHT0, GL::POSITION, lightPosition)
|
65
|
+
GL.Light(GL::LIGHT0, GL::AMBIENT, lightAmbient)
|
66
|
+
GL.Light(GL::LIGHT0, GL::DIFFUSE, lightDiffuse)
|
67
|
+
GL.Enable(GL::LIGHT0)
|
68
|
+
GL.Enable(GL::LIGHTING)
|
69
|
+
|
70
|
+
GL.PushMatrix()
|
71
|
+
drawTerrain(@p_width.to_s.to_i, @p_length.to_s.to_i)
|
72
|
+
GL.PopMatrix()
|
73
|
+
|
74
|
+
# Swap if it is double-buffered
|
75
|
+
if @glvisual.isDoubleBuffer
|
76
|
+
@glcanvas.swapBuffers
|
77
|
+
end
|
78
|
+
|
79
|
+
# Make context non-current
|
80
|
+
@glcanvas.makeNonCurrent
|
81
|
+
end
|
82
|
+
|
83
|
+
def initialize(app)
|
84
|
+
@p_seed = FXDataTarget.new(rand(100))
|
85
|
+
@p_freq = FXDataTarget.new(1.0)
|
86
|
+
@p_octave = FXDataTarget.new(1)
|
87
|
+
@p_width = FXDataTarget.new(10)
|
88
|
+
@p_length = FXDataTarget.new(10)
|
89
|
+
|
90
|
+
# Invoke the base class initializer
|
91
|
+
super(app, "Perlin Visualizer", :opts => DECOR_ALL, :width => 800, :height => 600)
|
92
|
+
|
93
|
+
# Construct the main window elements
|
94
|
+
frame = FXHorizontalFrame.new(self, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y)
|
95
|
+
frame.padLeft, frame.padRight = 0, 0
|
96
|
+
frame.padTop, frame.padBottom = 0, 0
|
97
|
+
|
98
|
+
# Left pane to contain the glcanvas
|
99
|
+
glcanvasFrame = FXVerticalFrame.new(frame, LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_TOP | LAYOUT_LEFT)
|
100
|
+
|
101
|
+
# Drawing glcanvas
|
102
|
+
glpanel = FXVerticalFrame.new(
|
103
|
+
glcanvasFrame, (FRAME_SUNKEN | FRAME_THICK | LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_TOP | LAYOUT_LEFT)
|
104
|
+
)
|
105
|
+
glpanel.padLeft, glpanel.padRight = 0, 0
|
106
|
+
glpanel.padTop, glpanel.padBottom = 0, 0
|
107
|
+
|
108
|
+
# A visual to draw OpenGL
|
109
|
+
@glvisual = FXGLVisual.new(getApp(), VISUAL_DOUBLEBUFFER)
|
110
|
+
|
111
|
+
# Drawing glcanvas
|
112
|
+
@glcanvas = FXGLCanvas.new(glpanel, @glvisual, :opts => LAYOUT_FILL_X | LAYOUT_FILL_Y | LAYOUT_TOP | LAYOUT_LEFT)
|
113
|
+
@glcanvas.connect(SEL_PAINT) { drawScene }
|
114
|
+
@glcanvas.connect(SEL_CONFIGURE) do
|
115
|
+
if @glcanvas.makeCurrent
|
116
|
+
GL.Viewport(0, 0, @glcanvas.width, @glcanvas.height)
|
117
|
+
@glcanvas.makeNonCurrent
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Right pane for the buttons
|
122
|
+
buttonFrame = FXVerticalFrame.new(frame, LAYOUT_FILL_Y | LAYOUT_TOP | LAYOUT_LEFT)
|
123
|
+
buttonFrame.padLeft, buttonFrame.padRight = 10, 10
|
124
|
+
buttonFrame.padTop, buttonFrame.padBottom = 10, 10
|
125
|
+
|
126
|
+
# Redraw button
|
127
|
+
redrawBtn = FXButton.new(
|
128
|
+
buttonFrame,
|
129
|
+
"&Redraw\tRedraw the screen",
|
130
|
+
:opts => FRAME_THICK | FRAME_RAISED | LAYOUT_FILL_X | LAYOUT_TOP | LAYOUT_LEFT
|
131
|
+
)
|
132
|
+
redrawBtn.connect(SEL_COMMAND) do
|
133
|
+
x = (@p_width.to_s.to_i / 2.0)
|
134
|
+
y = (@p_length.to_s.to_i / 2.0)
|
135
|
+
GLU.LookAt(0.0, 0.0, 10.0, x, y, 0.0, 0.0, 1.0, 0.0)
|
136
|
+
drawScene
|
137
|
+
end
|
138
|
+
redrawBtn.padLeft, redrawBtn.padRight = 10, 10
|
139
|
+
redrawBtn.padTop, redrawBtn.padBottom = 5, 5
|
140
|
+
|
141
|
+
# Redraw button
|
142
|
+
redrawRndBtn = FXButton.new(
|
143
|
+
buttonFrame,
|
144
|
+
"&Redraw Random\tRedraw the screen after changing the seed",
|
145
|
+
:opts => FRAME_THICK | FRAME_RAISED | LAYOUT_FILL_X | LAYOUT_TOP | LAYOUT_LEFT
|
146
|
+
)
|
147
|
+
redrawRndBtn.connect(SEL_COMMAND) do
|
148
|
+
@p_seed = FXDataTarget.new(rand(100))
|
149
|
+
drawScene
|
150
|
+
end
|
151
|
+
redrawRndBtn.padLeft, redrawRndBtn.padRight = 10, 10
|
152
|
+
redrawRndBtn.padTop, redrawRndBtn.padBottom = 5, 5
|
153
|
+
|
154
|
+
FXLabel.new(buttonFrame, "Seed", nil, LAYOUT_CENTER_Y | LAYOUT_CENTER_X | JUSTIFY_RIGHT | LAYOUT_FILL_ROW)
|
155
|
+
FXTextField.new(buttonFrame, 10, @p_seed, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER | LAYOUT_FILL_ROW)
|
156
|
+
|
157
|
+
FXLabel.new(buttonFrame, "Frequency", nil, LAYOUT_CENTER_Y | LAYOUT_CENTER_X | JUSTIFY_RIGHT | LAYOUT_FILL_ROW)
|
158
|
+
FXTextField.new(buttonFrame, 10, @p_freq, FXDataTarget::ID_VALUE, TEXTFIELD_REAL | LAYOUT_FILL_ROW)
|
159
|
+
|
160
|
+
FXLabel.new(buttonFrame, "Octave", nil, LAYOUT_CENTER_Y | LAYOUT_CENTER_X | JUSTIFY_RIGHT | LAYOUT_FILL_ROW)
|
161
|
+
FXTextField.new(buttonFrame, 10, @p_octave, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER | LAYOUT_FILL_ROW)
|
162
|
+
|
163
|
+
FXLabel.new(buttonFrame, "Width", nil, LAYOUT_CENTER_Y | LAYOUT_CENTER_X | JUSTIFY_RIGHT | LAYOUT_FILL_ROW)
|
164
|
+
FXTextField.new(buttonFrame, 10, @p_width, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER | LAYOUT_FILL_ROW)
|
165
|
+
|
166
|
+
FXLabel.new(buttonFrame, "Length", nil, LAYOUT_CENTER_Y | LAYOUT_CENTER_X | JUSTIFY_RIGHT | LAYOUT_FILL_ROW)
|
167
|
+
FXTextField.new(buttonFrame, 10, @p_length, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER | LAYOUT_FILL_ROW)
|
168
|
+
|
169
|
+
# Exit button
|
170
|
+
exitBtn = FXButton.new(
|
171
|
+
buttonFrame,
|
172
|
+
"&Exit\tExit the application", nil,
|
173
|
+
getApp(),
|
174
|
+
FXApp::ID_QUIT,
|
175
|
+
FRAME_THICK | FRAME_RAISED | LAYOUT_FILL_X | LAYOUT_TOP | LAYOUT_LEFT
|
176
|
+
)
|
177
|
+
exitBtn.padLeft, exitBtn.padRight = 10, 10
|
178
|
+
exitBtn.padTop, exitBtn.padBottom = 5, 5
|
179
|
+
end
|
180
|
+
|
181
|
+
# Create and initialize
|
182
|
+
def create
|
183
|
+
super
|
184
|
+
show(PLACEMENT_SCREEN)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
if __FILE__ == $0
|
189
|
+
application = FXApp.new("Perlin Data Viewer", "Perlin Data View")
|
190
|
+
application.disableThreads
|
191
|
+
|
192
|
+
# Construct the main window
|
193
|
+
GLTestWindow.new(application)
|
194
|
+
|
195
|
+
# Create the app's windows
|
196
|
+
application.create
|
197
|
+
|
198
|
+
# Run the application
|
199
|
+
application.run
|
200
|
+
end
|