ruby-opengl 0.50.0 → 0.60.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/Rakefile +15 -11
  2. data/doc/build_install.txt +10 -6
  3. data/doc/extensions.txt.in +348 -0
  4. data/doc/history.txt +4 -0
  5. data/doc/roadmap.txt +4 -6
  6. data/doc/scientific_use.txt +7 -0
  7. data/doc/supplies/page_template.html +2 -1
  8. data/doc/thanks.txt +5 -0
  9. data/doc/tutorial.txt +431 -121
  10. data/examples/NeHe/nehe_lesson02.rb +1 -1
  11. data/examples/NeHe/nehe_lesson03.rb +1 -1
  12. data/examples/NeHe/nehe_lesson04.rb +1 -1
  13. data/examples/NeHe/nehe_lesson05.rb +1 -1
  14. data/examples/NeHe/nehe_lesson36.rb +1 -1
  15. data/examples/OrangeBook/brick.rb +3 -15
  16. data/examples/OrangeBook/particle.rb +2 -20
  17. data/examples/RedBook/aapoly.rb +1 -1
  18. data/examples/RedBook/aargb.rb +2 -2
  19. data/examples/RedBook/accanti.rb +1 -1
  20. data/examples/RedBook/accpersp.rb +1 -1
  21. data/examples/RedBook/alpha.rb +2 -2
  22. data/examples/RedBook/alpha3D.rb +1 -1
  23. data/examples/RedBook/bezcurve.rb +1 -1
  24. data/examples/RedBook/bezmesh.rb +1 -1
  25. data/examples/RedBook/checker.rb +1 -1
  26. data/examples/RedBook/clip.rb +1 -1
  27. data/examples/RedBook/colormat.rb +1 -1
  28. data/examples/RedBook/cube.rb +1 -1
  29. data/examples/RedBook/depthcue.rb +1 -1
  30. data/examples/RedBook/dof.rb +1 -1
  31. data/examples/RedBook/double.rb +1 -1
  32. data/examples/RedBook/drawf.rb +1 -1
  33. data/examples/RedBook/feedback.rb +1 -1
  34. data/examples/RedBook/fog.rb +1 -1
  35. data/examples/RedBook/font.rb +2 -2
  36. data/examples/RedBook/hello.rb +1 -1
  37. data/examples/RedBook/image.rb +4 -4
  38. data/examples/RedBook/lines.rb +1 -1
  39. data/examples/RedBook/list.rb +1 -1
  40. data/examples/RedBook/material.rb +1 -1
  41. data/examples/RedBook/mipmap.rb +1 -1
  42. data/examples/RedBook/model.rb +1 -1
  43. data/examples/RedBook/movelight.rb +1 -1
  44. data/examples/RedBook/pickdepth.rb +1 -1
  45. data/examples/RedBook/planet.rb +5 -5
  46. data/examples/RedBook/quadric.rb +1 -1
  47. data/examples/RedBook/robot.rb +5 -5
  48. data/examples/RedBook/select.rb +1 -1
  49. data/examples/RedBook/smooth.rb +1 -1
  50. data/examples/RedBook/stencil.rb +1 -1
  51. data/examples/RedBook/stroke.rb +2 -2
  52. data/examples/RedBook/surface.rb +1 -1
  53. data/examples/RedBook/teaambient.rb +1 -1
  54. data/examples/RedBook/teapots.rb +1 -1
  55. data/examples/RedBook/tess.rb +1 -1
  56. data/examples/RedBook/texbind.rb +1 -1
  57. data/examples/RedBook/texgen.rb +5 -5
  58. data/examples/RedBook/texturesurf.rb +1 -1
  59. data/examples/RedBook/varray.rb +1 -1
  60. data/examples/RedBook/wrap.rb +5 -5
  61. data/examples/misc/OGLBench.rb +337 -0
  62. data/examples/misc/anisotropic.rb +1 -1
  63. data/examples/misc/fbo_test.rb +356 -0
  64. data/examples/misc/font-glut.rb +1 -1
  65. data/examples/misc/glfwtest.rb +30 -0
  66. data/examples/misc/md2model.rb +15 -0
  67. data/examples/misc/plane.rb +1 -1
  68. data/examples/misc/readpixel.rb +1 -1
  69. data/examples/misc/sdltest.rb +34 -0
  70. data/examples/misc/trislam.rb +828 -0
  71. data/ext/common/common.h +126 -218
  72. data/ext/common/conv.h +244 -0
  73. data/ext/common/funcdef.h +280 -0
  74. data/ext/common/gl-error.h +23 -0
  75. data/ext/common/gl-types.h +14 -0
  76. data/ext/gl/gl-1.0-1.1.c +497 -1255
  77. data/ext/gl/gl-1.2.c +121 -304
  78. data/ext/gl/gl-1.3.c +78 -339
  79. data/ext/gl/gl-1.4.c +102 -164
  80. data/ext/gl/gl-1.5.c +42 -173
  81. data/ext/gl/gl-2.0.c +273 -1039
  82. data/ext/gl/gl-2.1.c +15 -19
  83. data/ext/gl/gl-enums.c +3 -2
  84. data/ext/gl/gl-error.c +104 -0
  85. data/ext/gl/gl-ext-3dfx.c +27 -0
  86. data/ext/gl/gl-ext-arb.c +812 -12
  87. data/ext/gl/gl-ext-ati.c +41 -0
  88. data/ext/gl/gl-ext-ext.c +791 -119
  89. data/ext/gl/gl-ext-gremedy.c +41 -0
  90. data/ext/gl/gl-ext-nv.c +679 -0
  91. data/ext/gl/gl.c +48 -28
  92. data/ext/gl/mkrf_conf.rb +13 -10
  93. data/ext/glu/glu-enums.c +3 -2
  94. data/ext/glu/glu.c +136 -41
  95. data/ext/glu/mkrf_conf.rb +15 -12
  96. data/ext/glut/glut.c +37 -80
  97. data/ext/glut/mkrf_conf.rb +17 -13
  98. data/lib/opengl.rb +29 -53
  99. data/test/tc_common.rb +9 -3
  100. data/test/tc_ext_arb.rb +397 -3
  101. data/test/tc_ext_ati.rb +33 -0
  102. data/test/tc_ext_ext.rb +479 -2
  103. data/test/tc_ext_gremedy.rb +36 -0
  104. data/test/tc_ext_nv.rb +357 -0
  105. data/test/tc_func_10_11.rb +93 -67
  106. data/test/tc_func_12.rb +11 -11
  107. data/test/tc_func_13.rb +38 -18
  108. data/test/tc_func_14.rb +2 -2
  109. data/test/tc_func_15.rb +10 -10
  110. data/test/tc_func_20.rb +20 -20
  111. data/test/tc_func_21.rb +53 -22
  112. data/test/tc_glu.rb +9 -4
  113. data/test/tc_misc.rb +15 -2
  114. metadata +22 -8
  115. data/doc/extensions.txt +0 -361
  116. data/examples/RedBook/aaindex.rb +0 -97
  117. data/examples/misc/smooth.rb +0 -42
  118. data/examples/misc/test.rb +0 -65
@@ -0,0 +1,828 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Purpose: Determine performance curves for various methods of pushing
4
+ # triangles and quads through the OpenGL pipeline
5
+
6
+ # Copyright (c) 2004-2006, Geoff Broadwell; this script is released
7
+ # as open source and may be distributed and modified under the terms
8
+ # of either the Artistic License or the GNU General Public License,
9
+ # in the same manner as Perl itself. These licenses should have been
10
+ # distributed to you as part of your Perl distribution, and can be
11
+ # read using `perldoc perlartistic` and `perldoc perlgpl` respectively.
12
+
13
+ # Conversion to ruby by Jan Dvorak <jan.dvorak@kraxnet.cz>
14
+
15
+ require 'opengl'
16
+ include Gl,Glu,Glut
17
+
18
+ require 'mathn'
19
+
20
+ require 'OGLBench'
21
+
22
+ $VERSION = '0.1.24-ruby-p1'
23
+
24
+ $test = 0
25
+ $run = 0
26
+ $done = false
27
+ $ready = false
28
+
29
+ ### USER CONFIG
30
+
31
+ # Primitive sizes (and therefore counts) are integer divisors of
32
+ # (A^i * B^j * C^k ...) where good A, B, C, ... are relatively prime;
33
+ # this number is used for the draw area height and width and defaults to:
34
+ # 2^4 * 3^2 * 5 = 720
35
+ # You may also want to get fewer data points across the same range by
36
+ # directly using higher powers; for example:
37
+ # 16 * 9 * 5 = 720
38
+ #
39
+ # my @max_powers = (16 => 1, 9 => 1, 5 => 1);
40
+ $max_powers = { 2 => 4, 3 => 2, 5 => 1 }.to_a.flatten
41
+
42
+ # Maximum quads along each axis for known slow versus usually fast tests;
43
+ # chosen to be somewhat reasonable for most common settings of @max_powers
44
+ # my $max_count_slow = 60;
45
+ $max_count_slow = 154
46
+ $max_count_fast = 154
47
+
48
+ # Font to use to label graphs
49
+ $font_style = GLUT_BITMAP_HELVETICA_10
50
+
51
+ ### MISC GLOBALS
52
+
53
+ $conf = $app = $gl_info = nil
54
+ $MIN_FRAMES = $MIN_SECONDS = 0
55
+ $w = $h = 0
56
+ $dls = {}
57
+ $vas = {}
58
+ $combos = $slow = $fast = 0
59
+ $showing_graph = false
60
+ $empty_time = $empty_frames = $total = 0
61
+ $max = []
62
+ $stats = []
63
+ $stats_fixed = []
64
+
65
+ ### CODE
66
+
67
+ def main
68
+ init()
69
+ print "Benchmarks:"
70
+
71
+ glutDisplayFunc(method(:cbDraw).to_proc)
72
+ glutIdleFunc(method(:cbDraw).to_proc)
73
+ glutKeyboardFunc(method(:cbKeyPressed).to_proc)
74
+ glutMainLoop()
75
+ end
76
+
77
+ def init
78
+ $stdout.sync = true
79
+
80
+ $combos = recurse_combos($max_powers)
81
+ $combos.sort!
82
+ $slow = $combos.select { |a| a <= $max_count_slow }
83
+ $fast = $combos.select { |a| a > $max_count_slow &&
84
+ a <= $max_count_slow }
85
+
86
+ # Choose drawing area size to match counts
87
+ $h = $w = $combos.last
88
+
89
+ default_conf = {
90
+ :title => 'Triangle Slammer OpenGL Benchmark',
91
+ :geometry => "#{$w}x#{$h}",
92
+ :frames => 10,
93
+ :seconds => 1,
94
+ }
95
+ $conf, $app, $gl_info = OGLBench.basic_init(default_conf)
96
+
97
+
98
+ # Reduce indirections in inner loops
99
+ $MIN_FRAMES, $MIN_SECONDS = $conf[:frames], $conf[:seconds]
100
+
101
+ # Let user know what's going on
102
+ show_user_message()
103
+
104
+ # Change projection to integer-pixel ortho
105
+ glMatrixMode(GL_PROJECTION)
106
+ glOrtho(0, $w, 0, $h, -1, 1)
107
+ glMatrixMode(GL_MODELVIEW)
108
+
109
+ # Make sure GL state is consistent for VA and DL creation
110
+ start_frame()
111
+
112
+ # Create vertex arrays and display lists outside timing loop
113
+ init_vertex_arrays()
114
+ init_display_lists()
115
+
116
+ # Clean up GL state
117
+ end_frame()
118
+ end
119
+
120
+ def recurse_combos(powers)
121
+ base, max_power, *rest = powers
122
+
123
+ return [1] if powers.size<1
124
+
125
+ combos = []
126
+ (0..max_power).each do |power|
127
+ multiplier = base ** power
128
+ recurse_combos(rest).each do |item|
129
+ combos << (item*multiplier)
130
+ end
131
+ end
132
+ combos
133
+ end
134
+
135
+ def show_user_message
136
+ print <<"EOM";
137
+ TRISLAM benchmarks several methods of pushing OpenGL primitives,
138
+ testing each method with various primitive counts and sizes.
139
+ During the benchmark, the test window will start out black, slowly
140
+ brightening to white as testing progresses. Once benchmarking is
141
+ complete, the collected data will be dumped in tabular form.
142
+
143
+ The configuration for this series of tests will be as follows:
144
+
145
+ EOM
146
+
147
+ OGLBench.show_basic_config($conf, $gl_info, $VERSION)
148
+
149
+ puts "standard runs: #{$slow.join(' ')}"
150
+ puts "extra fast runs: #{$fast.join(' ')}"
151
+ puts '-' * 79
152
+ end
153
+
154
+
155
+ def init_vertex_arrays
156
+ print "Init vertex arrays:"
157
+
158
+ $va_types.keys.sort.each do |type|
159
+ print " #{type}"
160
+ ($slow + $fast).each do |count|
161
+ data = $va_types[type].call(count, $w / count.to_f)
162
+ va = data.pack("f*")
163
+ $vas["#{type}_#{count}"] = va
164
+ end
165
+ end
166
+
167
+ print ".\n";
168
+ end
169
+
170
+ def init_display_lists
171
+ print "Init display lists:"
172
+
173
+ num_lists = $dl_types.size * ($slow + $fast).size
174
+ current = glGenLists(num_lists)
175
+
176
+ $dl_types.keys.sort.each do |type|
177
+ print " #{type}"
178
+ ($slow + $fast).each do |count|
179
+ $dls["#{type}_#{count}"] = current
180
+ glNewList(current, GL_COMPILE)
181
+ $dl_types[type].call(count, $w / count.to_f)
182
+ glEndList()
183
+ current += 1
184
+ end
185
+ end
186
+ puts "."
187
+ end
188
+
189
+ def benchmark
190
+ if ($test >= $tests.size)
191
+ print ".\n" if (!$done)
192
+ $done = true
193
+ return
194
+ end
195
+ name,draw,stats,class_ = $tests[$test]
196
+
197
+ counts = class_ == 'single' ? [1] : (class_ == 'slow' ? $slow : $slow + $fast)
198
+
199
+ if ($run == 0)
200
+ print " #{name}";
201
+
202
+ # After printing current test name, busy wait for a second
203
+ # so that the terminal can catch up and not do work while
204
+ # the GL timing is in progress
205
+ a = Time.now
206
+ while 1 > (Time.now - a) do end
207
+ end
208
+
209
+ count = counts[$run]
210
+ size = $w / count
211
+
212
+ OGLBench.fade_to_white(($test + ($run.to_f / counts.size)) / $tests.size)
213
+
214
+ run_done = 0
215
+ frames = 0
216
+ start = Time.now
217
+
218
+ while (run_done==0)
219
+ start_frame()
220
+ draw.call(count, size.to_f)
221
+ end_frame()
222
+
223
+ frames += 1
224
+ run_done = 1 if ($MIN_FRAMES <= frames &&
225
+ $MIN_SECONDS <= Time.now - start)
226
+ end
227
+ glFinish()
228
+ end_ = Time.now
229
+ time = end_ - start
230
+
231
+ $stats << [name,count,time,frames] + stats.call(count,size.to_f)
232
+
233
+ $run += 1
234
+ if ($run >= counts.size)
235
+ $test += 1
236
+ $run = 0
237
+ end
238
+ end
239
+
240
+ def cleanup
241
+ fixup_stats()
242
+ show_stats()
243
+ draw_stats()
244
+ end
245
+
246
+ def start_frame
247
+ glClear(GL_COLOR_BUFFER_BIT |
248
+ GL_DEPTH_BUFFER_BIT)
249
+ end
250
+
251
+ def end_frame
252
+ glFinish()
253
+ end
254
+
255
+ def fixup_stats
256
+ empty = $stats.shift
257
+
258
+ $empty_time = empty[2]
259
+ $empty_frames = empty[3]
260
+ empty_tpf = $empty_time.to_f / $empty_frames
261
+
262
+ $total = ['totl,','avg'] + [0] * 12
263
+ $max = ['max','max'] + [0] * 12
264
+
265
+ $stats.each do |stat|
266
+ name, count, time, frames, pixpf, prmpf, tpf, vpf = stat
267
+
268
+ # Subtract out empty loop time, and loop if negative result
269
+ # $time -= $empty_tpf * $frames;
270
+ if (time <= 0)
271
+ stat += [0] * 5
272
+ next
273
+ end
274
+
275
+ # Calc "work", the geometric mean of pixels and vertices
276
+ workpf = Math::sqrt(pixpf * vpf)
277
+
278
+ # Calc fps
279
+ fps = frames / time
280
+
281
+ # Calc other perf stats
282
+ pixps = pixpf * fps
283
+ prmps = prmpf * fps
284
+ tps = tpf * fps
285
+ vps = vpf * fps
286
+ wps = workpf * fps
287
+
288
+ # Add them to stat row
289
+ stat += [fps, pixps, prmps, tps, vps, wps]
290
+
291
+ # Convert per frame counts to totals
292
+ (4..7).each { |i| stat[i] *= frames }
293
+
294
+ # Update running totals
295
+ (2..7).each { |i| $total[i] += stat[i] }
296
+
297
+ # Update running maximums
298
+ (2..13).each do |i|
299
+ $max[i] = stat[i] if $max[i] < stat[i]
300
+ end
301
+
302
+ $stats_fixed << stat
303
+ end
304
+
305
+ # Calc averages for totals line
306
+ (8..13).each { |i| $total[i] = $total[i-5] / $total[2].to_f }
307
+
308
+ $ready = true
309
+ $stats = $stats_fixed
310
+ end
311
+
312
+
313
+ def show_stats
314
+ basic = ["Name","Cnt","Time"]
315
+ raw = ["Frms","Mpix","Kprim","Ktri","Kvert"]
316
+ calc = raw
317
+ scale = [ 0, 6, 3, 3, 3, ] * 2
318
+ header = basic + raw + calc
319
+ scale.map! {|n| 10 ** n }
320
+
321
+ g_form = "%9s%-*s %s\n"
322
+ h_form = '%-5s%3s %6s' + ' %5s' * raw.size + ' ' + ' %5s' * calc.size + "\n"
323
+ format = '%-5s%3s %6.3f' + ' %5d' * raw.size + ' ' + ' %5d' * calc.size + "\n"
324
+
325
+ printf(g_form, '', 6 * 5 + 8, 'MEASURED', 'PER SECOND')
326
+ printf(h_form, *header)
327
+ printf(format, "empty", 1, $empty_time, $empty_frames, *([0] * 9))
328
+ #
329
+
330
+ ($stats + [$total]).each do |stat|
331
+ st = stat.clone()
332
+ (0..scale.size-1).each do |i|
333
+ st[i + 3] /= scale[i]
334
+ end
335
+ printf(format,*st)
336
+ end
337
+ end
338
+
339
+
340
+ def make_quads_va(count,size)
341
+ data = []
342
+ (0 .. count-1).each do |y|
343
+ (0 .. count-1).each do |x|
344
+ data << x * size << y * size + size
345
+ data << x * size << y * size
346
+ data << x * size + size << y * size
347
+ data << x * size + size << y * size + size
348
+ end
349
+ end
350
+ data
351
+ end
352
+
353
+ def make_tris_va(count,size)
354
+ data = []
355
+ (0 .. count-1).each do |y|
356
+ (0 .. count-1).each do |x|
357
+ data << x * size << y * size + size
358
+ data << x * size << y * size
359
+ data << x * size + size << y * size + size
360
+
361
+ data << x * size + size << y * size + size
362
+ data << x * size << y * size
363
+ data << x * size + size << y * size
364
+ end
365
+ end
366
+ data
367
+ end
368
+
369
+ def make_qs_va(count,size)
370
+ data = []
371
+ (0 .. count-1).each do |y|
372
+ (0 .. count).each do |x|
373
+ data << x * size << y * size + size
374
+ data << x * size << y * size
375
+ end
376
+ end
377
+ data
378
+ end
379
+
380
+ def make_ts_va(count,size)
381
+ data = []
382
+ (0 .. count-1).each do |y|
383
+ (0 .. count).each do |x|
384
+ data << x * size << y * size + size
385
+ data << x * size << y * size
386
+ end
387
+ end
388
+ data
389
+ end
390
+
391
+ def draw_qs(count,size)
392
+ (0 .. count-1).each do |y|
393
+ glBegin(GL_QUAD_STRIP)
394
+ (0 .. count).each do |x|
395
+ glVertex2f(x * size, y * size + size)
396
+ glVertex2f(x * size, y * size )
397
+ end
398
+ glEnd()
399
+ end
400
+ end
401
+
402
+ def draw_ts(count,size)
403
+ (0 .. count-1).each do |y|
404
+ glBegin(GL_TRIANGLE_STRIP)
405
+ (0 .. count).each do |x|
406
+ glVertex2f(x * size, y * size + size)
407
+ glVertex2f(x * size, y * size )
408
+ end
409
+ glEnd()
410
+ end
411
+ end
412
+
413
+ def draw_qs_va(count,size)
414
+ va = $vas["qs_#{count}"]
415
+ row = 2 * (count + 1)
416
+
417
+ glEnableClientState(GL_VERTEX_ARRAY)
418
+ glVertexPointer(2, GL_FLOAT, 0, va)
419
+ (0 .. count-1).each do |y|
420
+ glDrawArrays(GL_QUAD_STRIP, y * row, row)
421
+ end
422
+ glDisableClientState(GL_VERTEX_ARRAY)
423
+ end
424
+
425
+ def draw_ts_va(count,size)
426
+ va = $vas["ts_#{count}"]
427
+ row = 2 * (count + 1)
428
+
429
+ glEnableClientState(GL_VERTEX_ARRAY)
430
+ glVertexPointer(2, GL_FLOAT, 0, va)
431
+ (0 .. count-1).each do |y|
432
+ glDrawArrays(GL_TRIANGLE_STRIP, y * row, row)
433
+ end
434
+ glDisableClientState(GL_VERTEX_ARRAY)
435
+ end
436
+
437
+ def draw_tris(count,size)
438
+ glBegin(GL_TRIANGLES)
439
+ (0 .. count-1).each do |y|
440
+ (0 .. count-1).each do |x|
441
+ glVertex2f(x * size , y * size + size)
442
+ glVertex2f(x * size , y * size )
443
+ glVertex2f(x * size + size, y * size + size)
444
+
445
+ glVertex2f(x * size + size, y * size + size)
446
+ glVertex2f(x * size , y * size )
447
+ glVertex2f(x * size + size, y * size )
448
+ end
449
+ end
450
+ glEnd
451
+ end
452
+
453
+ def stats_tris(count,size)
454
+ length = size * count
455
+ area = length * length
456
+ prims = 2 * count * count
457
+ tris = prims
458
+ verts = 3 * prims
459
+
460
+ [area, prims, tris, verts]
461
+ end
462
+
463
+ def draw_empty(count,size)
464
+ end
465
+
466
+ def stats_empty(count,size)
467
+ [0,0,0,0]
468
+ end
469
+
470
+ def draw_quads(count,size)
471
+ glBegin(GL_QUADS)
472
+ (0 .. count-1).each do |y|
473
+ (0 .. count-1).each do |x|
474
+ glVertex2f(x * size , y * size + size)
475
+ glVertex2f(x * size , y * size )
476
+ glVertex2f(x * size + size, y * size )
477
+ glVertex2f(x * size + size, y * size + size)
478
+ end
479
+ end
480
+ glEnd
481
+ end
482
+
483
+ def stats_quads(count,size)
484
+ length = size * count
485
+ area = length * length
486
+ prims = count * count
487
+ tris = 2 * prims
488
+ verts = 4 * prims
489
+
490
+ [area, prims, tris, verts]
491
+ end
492
+
493
+ def stats_ts(count,size)
494
+ length = size * count
495
+ area = length * length
496
+ prims = count
497
+ tris = 2 * count * prims
498
+ verts = 2 * (count + 1) * prims
499
+
500
+ [area, prims, tris, verts]
501
+ end
502
+
503
+ def stats_qs(count,size)
504
+ length = size * count
505
+ area = length * length
506
+ prims = count
507
+ tris = 2 * count * prims
508
+ verts = 2 * (count + 1) * prims
509
+
510
+ [area, prims, tris, verts]
511
+ end
512
+
513
+ def draw_ts_dl(count,size)
514
+ glCallList($dls["ts_#{count}"]);
515
+ end
516
+
517
+ def draw_qs_dl(count,size)
518
+ glCallList($dls["qs_#{count}"]);
519
+ end
520
+
521
+ def draw_tris_va(count,size)
522
+ va = $vas["t_#{count}"]
523
+
524
+ glVertexPointer(2, GL_FLOAT, 0, va)
525
+
526
+ glEnableClientState(GL_VERTEX_ARRAY)
527
+ glDrawArrays(GL_TRIANGLES, 0, 6 * count * count)
528
+ glDisableClientState(GL_VERTEX_ARRAY)
529
+ end
530
+
531
+ def draw_quads_va(count,size)
532
+ va = $vas["q_#{count}"]
533
+
534
+ glVertexPointer(2, GL_FLOAT, 0, va)
535
+
536
+ glEnableClientState(GL_VERTEX_ARRAY)
537
+ glDrawArrays(GL_QUADS, 0, 4 * count * count)
538
+ glDisableClientState(GL_VERTEX_ARRAY)
539
+ end
540
+
541
+
542
+ def draw_ts_va_dl(count,size)
543
+ va = $vas["ts_#{count}"]
544
+
545
+ glVertexPointer(2, GL_FLOAT, 0, va)
546
+
547
+ glEnableClientState(GL_VERTEX_ARRAY)
548
+ glCallList($dls["tsv_#{count}"])
549
+ glDisableClientState(GL_VERTEX_ARRAY)
550
+ end
551
+
552
+ def draw_qs_va_dl(count,size)
553
+ va = $vas["qs_#{count}"]
554
+
555
+ glVertexPointer(2, GL_FLOAT, 0, va)
556
+
557
+ glEnableClientState(GL_VERTEX_ARRAY)
558
+ glCallList($dls["qsv_#{count}"])
559
+ glDisableClientState(GL_VERTEX_ARRAY)
560
+ end
561
+
562
+
563
+ def draw_stats
564
+ return if (!$ready)
565
+
566
+ # Graph config
567
+ x_off = 10
568
+ y_off = 10
569
+ tick_size = 3
570
+ val_space = 50
571
+ key_size = 20
572
+ x_scale = ($w - 4 * x_off) / (2 * ($fast.last || $slow.last))
573
+ key_scale = ($h - 4 * y_off) / (2 * $tests.size)
574
+
575
+ # Get a fresh black frame for graphing
576
+ glClearColor(0, 0, 0, 1)
577
+ start_frame()
578
+
579
+ # Use antialiased lines
580
+ glEnable(GL_BLEND)
581
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
582
+ glEnable(GL_LINE_SMOOTH)
583
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
584
+
585
+ # Draw axis ticks
586
+ glColor3f(1, 1, 1);
587
+ glBegin(GL_LINES);
588
+
589
+ ([0] + $slow + $fast).each do |count|
590
+ x_tick = count * x_scale + x_off
591
+ glVertex2f(x_tick, y_off)
592
+ glVertex2f(x_tick, y_off - tick_size)
593
+ glVertex2f(x_tick, y_off + $h / 2)
594
+ glVertex2f(x_tick, y_off + $h / 2 - tick_size)
595
+ glVertex2f(x_tick + $w / 2, y_off + $h / 2)
596
+ glVertex2f(x_tick + $w / 2, y_off + $h / 2 - tick_size)
597
+ end
598
+ glEnd
599
+
600
+ x_tick = x_off + 3
601
+ val_max = (($h / 2 - 2 * y_off) / val_space).to_i
602
+
603
+ # Work
604
+ (0..val_max).each do |value|
605
+ y_tick = value * val_space + y_off
606
+
607
+ glBegin(GL_LINES)
608
+ glVertex2f(x_off, y_tick)
609
+ glVertex2f(x_off - tick_size, y_tick)
610
+ glEnd
611
+ end
612
+
613
+ # Pixels
614
+ value = 0
615
+ val_max = $max[9] / mag_scale($max[9])
616
+ y_scale = ($h - 4 * y_off) / (2 * val_max)
617
+ val_inc = tick_inc(val_max,5)
618
+
619
+ while (value < val_max)
620
+ y_tick = (value * y_scale) + y_off
621
+
622
+ glBegin(GL_LINES)
623
+ glVertex2f(x_off, y_tick + $h / 2)
624
+ glVertex2f(x_off - tick_size, y_tick + $h / 2)
625
+ glEnd
626
+ OGLBench.draw_string($font_style, value.to_s, x_tick, y_tick + $h / 2) if (value!=0)
627
+ value += val_inc
628
+ end
629
+
630
+ # Vertices
631
+ value = 0
632
+ val_max = $max[12] / mag_scale($max[12])
633
+ y_scale = ($h - 4 * y_off) / (2 * val_max)
634
+ val_inc = tick_inc(val_max,5)
635
+ while (value < val_max)
636
+ y_tick = (value * y_scale) + y_off
637
+
638
+ glBegin(GL_LINES)
639
+ glVertex2f(x_off + $w / 2, y_tick + $h / 2)
640
+ glVertex2f(x_off + $w / 2 - tick_size, y_tick + $h / 2)
641
+ glEnd
642
+
643
+ OGLBench.draw_string($font_style, value.to_s, x_tick + $w / 2, y_tick + $h / 2) if (value!=0)
644
+ value += val_inc
645
+ end
646
+
647
+ # Draw axes
648
+ glBegin(GL_LINE_STRIP)
649
+ glVertex2f(x_off, $h / 2 - y_off)
650
+ glVertex2f(x_off, y_off)
651
+ glVertex2f($w / 2 - x_off, y_off)
652
+ glEnd
653
+ glBegin(GL_LINE_STRIP)
654
+ glVertex2f(x_off, $h - y_off)
655
+ glVertex2f(x_off, $h / 2 + y_off)
656
+ glVertex2f($w / 2 - x_off, $h / 2 + y_off)
657
+ glEnd
658
+ glBegin(GL_LINE_STRIP)
659
+ glVertex2f($w / 2 + x_off, $h - y_off)
660
+ glVertex2f($w / 2 + x_off, $h / 2 + y_off)
661
+ glVertex2f($w - x_off, $h / 2 + y_off)
662
+ glEnd
663
+
664
+ # Draw color key
665
+ (0..$tests.size - 1).each do |num|
666
+ test = $tests[num]
667
+ name,color,stipple = [test[0]] + test[-2,2]
668
+ glEnable(GL_LINE_STIPPLE)
669
+ glLineStipple(3, stipple)
670
+
671
+ glBegin(GL_LINES)
672
+ glColor3fv(color)
673
+ glVertex2f(x_off + $w / 2, y_off + num * key_scale)
674
+ glVertex2f(x_off + $w / 2 + key_size, y_off + num * key_scale)
675
+ glEnd()
676
+
677
+ glDisable(GL_LINE_STIPPLE)
678
+
679
+ OGLBench.draw_string($font_style, name, x_off + $w / 2 + key_size * 2, y_off + num * key_scale)
680
+ end
681
+
682
+ # Draw performance graph lines
683
+
684
+ # Pixels per second
685
+ draw_one_stat(x_off, y_off + $h / 2, y_off, x_scale, 9)
686
+ glColor3f(1, 1, 1)
687
+
688
+ OGLBench.draw_string($font_style, mag_char($max[9]) + " Pixels/Sec", $w / 4, $h - 2 * y_off)
689
+
690
+ # Vertices per second
691
+ draw_one_stat(x_off + $w / 2, y_off + $h / 2, y_off, x_scale, 12)
692
+ glColor3f(1, 1, 1)
693
+ OGLBench.draw_string($font_style, mag_char($max[12]) + " Vertices/Sec", 3 * $w / 4, $h - 2 * y_off)
694
+
695
+ # "Work" per second, the geometric mean of pixels and vertices
696
+ draw_one_stat(x_off, y_off, y_off, x_scale, 13)
697
+ glColor3f(1, 1, 1)
698
+
699
+ OGLBench.draw_string($font_style, "Work/Sec", $w / 4, $h / 2 - 2 * y_off)
700
+
701
+ # Show our graph
702
+ end_frame();
703
+ $showing_graph = true
704
+ end
705
+
706
+ def draw_one_stat(x_loc,y_loc,y_off,x_scale,num)
707
+ max = $max[num]
708
+ y_scale = ($h - 4 * y_off) / (2 * max)
709
+ colors = {}
710
+ $tests.each do |test| colors[test[0]] = test[-2] end
711
+
712
+ stipple = {}
713
+ $tests.each do |test| stipple[test[0]] = test[-1] end
714
+
715
+ last = ''
716
+
717
+ glEnable(GL_LINE_STIPPLE)
718
+ glBegin(GL_LINE_STRIP)
719
+ $stats.each_with_index do |stat,run|
720
+ name,count, st = stat[0,2] + [stat[num]]
721
+
722
+ if name != last
723
+ glEnd
724
+ glLineStipple(3, stipple[name])
725
+ glBegin(GL_LINE_STRIP)
726
+ last = name
727
+ end
728
+
729
+ glColor3fv(colors[name])
730
+ glVertex2f(count * x_scale + x_loc, st * y_scale + y_loc)
731
+ end
732
+ glEnd
733
+ glDisable(GL_LINE_STIPPLE)
734
+ end
735
+
736
+
737
+ def kilo_mag(num)
738
+ mag = (Math::log(num) / Math::log(10)).to_i
739
+ (mag / 3)
740
+ end
741
+
742
+ def mag_char(num)
743
+ ['','K','M','G','T','P','E','Z','Y'][kilo_mag(num)]
744
+ end
745
+
746
+ def mag_scale(num)
747
+ 10 ** (3*kilo_mag(num))
748
+ end
749
+
750
+ def tick_inc(max,parts = 5)
751
+ return (max / parts.to_f) if (max < 1)
752
+
753
+ mag = (Math::log(max) / Math::log(10)).to_i
754
+ scl = (10 ** (mag - 1))
755
+ inc = max / (scl * parts)
756
+
757
+ if (inc > 7.5)
758
+ inc = 10
759
+ elsif (inc > 3.5)
760
+ inc = 5
761
+ elsif (inc > 1.5)
762
+ inc = 2
763
+ else
764
+ inc = 1
765
+ end
766
+ (inc * scl.to_f)
767
+ end
768
+
769
+ # State engine
770
+ def cbDraw
771
+ if (!$done)
772
+ benchmark()
773
+ elsif (!$ready)
774
+ cleanup()
775
+ else
776
+ sleep(1)
777
+ draw_stats()
778
+ end
779
+ end
780
+
781
+ # Keyboard handler
782
+ def cbKeyPressed(key,x,y)
783
+ if (key == ?\e or key == ?q)
784
+ glutDestroyWindow($app)
785
+ exit(0)
786
+ end
787
+ if ($done && key == ?r)
788
+ draw_stats()
789
+ end
790
+ end
791
+
792
+
793
+ ### METHODS TO BENCHMARK
794
+
795
+ $va_types = {
796
+ "q" => method(:make_quads_va),
797
+ "t" => method(:make_tris_va),
798
+ "qs" => method(:make_qs_va),
799
+ "ts" => method(:make_ts_va),
800
+ }
801
+
802
+ $dl_types = {
803
+ "qs" => method(:draw_qs),
804
+ "ts" => method(:draw_ts),
805
+ "qsv" => method(:draw_qs_va),
806
+ "tsv" => method(:draw_ts_va),
807
+ }
808
+
809
+ $tests = [
810
+ # Nick Draw Routine Stats Calc Type Graph Color
811
+ # ["empty",method(:draw_empty), method(:stats_empty),'single',[1 , 1, 1], 0xFFFF],
812
+ ["t" ,method(:draw_tris), method(:stats_tris) ,'slow', [1 , 0, 0], 0xAAAA],
813
+ ["q" ,method(:draw_quads), method(:stats_quads),'slow', [1 ,0.5, 0], 0xAAAA],
814
+ ["ts" ,method(:draw_ts), method(:stats_ts), 'slow', [1 , 1, 0], 0xAAAA],
815
+ ["qs" ,method(:draw_qs), method(:stats_qs), 'slow', [0 , 1, 0], 0xAAAA],
816
+ ["tsd" ,method(:draw_ts_dl), method(:stats_ts), 'fast', [0 , 1, 1], 0xAAAA],
817
+ ["qsd" ,method(:draw_qs_dl), method(:stats_qs), 'fast', [0 , 0, 1], 0xAAAA],
818
+ ["tv" ,method(:draw_tris_va), method(:stats_tris), 'fast', [0.8, 0, 0], 0xFFFF],
819
+ ["qv" ,method(:draw_quads_va),method(:stats_quads),'fast', [0.8,0.4, 0], 0xFFFF],
820
+ ["tsv" ,method(:draw_ts_va), method(:stats_ts), 'fast', [0.8,0.8, 0], 0xFFFF],
821
+ ["qsv" ,method(:draw_qs_va), method(:stats_qs), 'fast', [0 ,0.8, 0], 0xFFFF],
822
+ ["tsvd" ,method(:draw_ts_va_dl),method(:stats_ts), 'fast', [0 ,0.8,0.8], 0xFFFF],
823
+ ["qsvd" ,method(:draw_qs_va_dl),method(:stats_qs), 'fast', [0 , 0,0.8], 0xFFFF],
824
+ ]
825
+
826
+ # Start from main function ()
827
+ main()
828
+