joonsrenderer 1.1-java

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 (255) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +53 -0
  3. data/.mvn/extensions.xml +8 -0
  4. data/CHANGELOG.md +2 -0
  5. data/Gemfile +6 -0
  6. data/LICENSE +674 -0
  7. data/README.md +2 -0
  8. data/Rakefile +43 -0
  9. data/docs/.gitignore +6 -0
  10. data/docs/_config.yml +20 -0
  11. data/docs/_includes/footer.html +38 -0
  12. data/docs/_includes/head.html +15 -0
  13. data/docs/_includes/header.html +27 -0
  14. data/docs/_includes/icon-github.html +1 -0
  15. data/docs/_includes/icon-github.svg +1 -0
  16. data/docs/_includes/icon-twitter.html +1 -0
  17. data/docs/_includes/icon-twitter.svg +1 -0
  18. data/docs/_layouts/default.html +20 -0
  19. data/docs/_layouts/page.html +14 -0
  20. data/docs/_layouts/post.html +15 -0
  21. data/docs/_posts/2017-01-08-animated_ray_tracing.md +72 -0
  22. data/docs/_posts/2017-01-08-welcome.md +78 -0
  23. data/docs/_sass/_base.scss +206 -0
  24. data/docs/_sass/_layout.scss +242 -0
  25. data/docs/_sass/_syntax-highlighting.scss +71 -0
  26. data/docs/about.md +12 -0
  27. data/docs/assets/Animation.ogv +0 -0
  28. data/docs/assets/Animation.png +0 -0
  29. data/docs/assets/basic.png +0 -0
  30. data/docs/assets/basic_traced.png +0 -0
  31. data/docs/css/main.scss +38 -0
  32. data/docs/favicon.ico +0 -0
  33. data/docs/feed.xml +30 -0
  34. data/docs/index.html +38 -0
  35. data/joonsrenderer.gemspec +23 -0
  36. data/lib/joonsrenderer.rb +12 -0
  37. data/lib/joonsrenderer/version.rb +3 -0
  38. data/pom.rb +75 -0
  39. data/pom.xml +163 -0
  40. data/src/main/java/SunflowGUI.java +1354 -0
  41. data/src/main/java/joons/JRFiller.java +79 -0
  42. data/src/main/java/joons/JRImagePanel.java +141 -0
  43. data/src/main/java/joons/JRRecorder.java +183 -0
  44. data/src/main/java/joons/JRStatics.java +199 -0
  45. data/src/main/java/joons/JoonsRenderer.java +837 -0
  46. data/src/main/java/org/sunflow/AsciiFileSunflowAPI.java +98 -0
  47. data/src/main/java/org/sunflow/Benchmark.java +313 -0
  48. data/src/main/java/org/sunflow/BinaryFileSunflowAPI.java +228 -0
  49. data/src/main/java/org/sunflow/FileSunflowAPI.java +354 -0
  50. data/src/main/java/org/sunflow/PluginRegistry.java +322 -0
  51. data/src/main/java/org/sunflow/RealtimeBenchmark.java +125 -0
  52. data/src/main/java/org/sunflow/RenderObjectMap.java +344 -0
  53. data/src/main/java/org/sunflow/SunflowAPI.java +762 -0
  54. data/src/main/java/org/sunflow/SunflowAPIInterface.java +277 -0
  55. data/src/main/java/org/sunflow/core/AccelerationStructure.java +20 -0
  56. data/src/main/java/org/sunflow/core/AccelerationStructureFactory.java +36 -0
  57. data/src/main/java/org/sunflow/core/BucketOrder.java +21 -0
  58. data/src/main/java/org/sunflow/core/Camera.java +125 -0
  59. data/src/main/java/org/sunflow/core/CameraLens.java +29 -0
  60. data/src/main/java/org/sunflow/core/CausticPhotonMapInterface.java +15 -0
  61. data/src/main/java/org/sunflow/core/Display.java +78 -0
  62. data/src/main/java/org/sunflow/core/Filter.java +27 -0
  63. data/src/main/java/org/sunflow/core/GIEngine.java +42 -0
  64. data/src/main/java/org/sunflow/core/Geometry.java +157 -0
  65. data/src/main/java/org/sunflow/core/GlobalPhotonMapInterface.java +21 -0
  66. data/src/main/java/org/sunflow/core/ImageSampler.java +26 -0
  67. data/src/main/java/org/sunflow/core/Instance.java +224 -0
  68. data/src/main/java/org/sunflow/core/InstanceList.java +83 -0
  69. data/src/main/java/org/sunflow/core/IntersectionState.java +120 -0
  70. data/src/main/java/org/sunflow/core/LightSample.java +104 -0
  71. data/src/main/java/org/sunflow/core/LightServer.java +382 -0
  72. data/src/main/java/org/sunflow/core/LightSource.java +67 -0
  73. data/src/main/java/org/sunflow/core/Modifier.java +16 -0
  74. data/src/main/java/org/sunflow/core/Options.java +20 -0
  75. data/src/main/java/org/sunflow/core/ParameterList.java +758 -0
  76. data/src/main/java/org/sunflow/core/PhotonStore.java +62 -0
  77. data/src/main/java/org/sunflow/core/PrimitiveList.java +70 -0
  78. data/src/main/java/org/sunflow/core/Ray.java +219 -0
  79. data/src/main/java/org/sunflow/core/RenderObject.java +25 -0
  80. data/src/main/java/org/sunflow/core/Scene.java +377 -0
  81. data/src/main/java/org/sunflow/core/SceneParser.java +58 -0
  82. data/src/main/java/org/sunflow/core/Shader.java +30 -0
  83. data/src/main/java/org/sunflow/core/ShadingCache.java +84 -0
  84. data/src/main/java/org/sunflow/core/ShadingState.java +939 -0
  85. data/src/main/java/org/sunflow/core/Statistics.java +85 -0
  86. data/src/main/java/org/sunflow/core/Tesselatable.java +36 -0
  87. data/src/main/java/org/sunflow/core/Texture.java +128 -0
  88. data/src/main/java/org/sunflow/core/TextureCache.java +48 -0
  89. data/src/main/java/org/sunflow/core/accel/BoundingIntervalHierarchy.java +652 -0
  90. data/src/main/java/org/sunflow/core/accel/KDTree.java +833 -0
  91. data/src/main/java/org/sunflow/core/accel/NullAccelerator.java +30 -0
  92. data/src/main/java/org/sunflow/core/accel/UniformGrid.java +329 -0
  93. data/src/main/java/org/sunflow/core/bucket/BucketOrderFactory.java +26 -0
  94. data/src/main/java/org/sunflow/core/bucket/ColumnBucketOrder.java +21 -0
  95. data/src/main/java/org/sunflow/core/bucket/DiagonalBucketOrder.java +28 -0
  96. data/src/main/java/org/sunflow/core/bucket/HilbertBucketOrder.java +65 -0
  97. data/src/main/java/org/sunflow/core/bucket/InvertedBucketOrder.java +28 -0
  98. data/src/main/java/org/sunflow/core/bucket/RandomBucketOrder.java +49 -0
  99. data/src/main/java/org/sunflow/core/bucket/RowBucketOrder.java +21 -0
  100. data/src/main/java/org/sunflow/core/bucket/SpiralBucketOrder.java +43 -0
  101. data/src/main/java/org/sunflow/core/camera/FisheyeLens.java +25 -0
  102. data/src/main/java/org/sunflow/core/camera/PinholeLens.java +43 -0
  103. data/src/main/java/org/sunflow/core/camera/SphericalLens.java +22 -0
  104. data/src/main/java/org/sunflow/core/camera/ThinLens.java +107 -0
  105. data/src/main/java/org/sunflow/core/display/FastDisplay.java +119 -0
  106. data/src/main/java/org/sunflow/core/display/FileDisplay.java +83 -0
  107. data/src/main/java/org/sunflow/core/display/FrameDisplay.java +97 -0
  108. data/src/main/java/org/sunflow/core/display/ImgPipeDisplay.java +109 -0
  109. data/src/main/java/org/sunflow/core/filter/BlackmanHarrisFilter.java +28 -0
  110. data/src/main/java/org/sunflow/core/filter/BoxFilter.java +16 -0
  111. data/src/main/java/org/sunflow/core/filter/CatmullRomFilter.java +29 -0
  112. data/src/main/java/org/sunflow/core/filter/CubicBSpline.java +32 -0
  113. data/src/main/java/org/sunflow/core/filter/GaussianFilter.java +24 -0
  114. data/src/main/java/org/sunflow/core/filter/LanczosFilter.java +30 -0
  115. data/src/main/java/org/sunflow/core/filter/MitchellFilter.java +28 -0
  116. data/src/main/java/org/sunflow/core/filter/SincFilter.java +25 -0
  117. data/src/main/java/org/sunflow/core/filter/TriangleFilter.java +16 -0
  118. data/src/main/java/org/sunflow/core/gi/AmbientOcclusionGIEngine.java +57 -0
  119. data/src/main/java/org/sunflow/core/gi/FakeGIEngine.java +48 -0
  120. data/src/main/java/org/sunflow/core/gi/InstantGI.java +194 -0
  121. data/src/main/java/org/sunflow/core/gi/IrradianceCacheGIEngine.java +268 -0
  122. data/src/main/java/org/sunflow/core/gi/PathTracingGIEngine.java +65 -0
  123. data/src/main/java/org/sunflow/core/light/DirectionalSpotlight.java +103 -0
  124. data/src/main/java/org/sunflow/core/light/ImageBasedLight.java +303 -0
  125. data/src/main/java/org/sunflow/core/light/PointLight.java +72 -0
  126. data/src/main/java/org/sunflow/core/light/SphereLight.java +166 -0
  127. data/src/main/java/org/sunflow/core/light/SunSkyLight.java +362 -0
  128. data/src/main/java/org/sunflow/core/light/TriangleMeshLight.java +296 -0
  129. data/src/main/java/org/sunflow/core/modifiers/BumpMappingModifier.java +37 -0
  130. data/src/main/java/org/sunflow/core/modifiers/NormalMapModifier.java +34 -0
  131. data/src/main/java/org/sunflow/core/modifiers/PerlinModifier.java +80 -0
  132. data/src/main/java/org/sunflow/core/parser/Keyword.java +39 -0
  133. data/src/main/java/org/sunflow/core/parser/RA2Parser.java +107 -0
  134. data/src/main/java/org/sunflow/core/parser/RA3Parser.java +68 -0
  135. data/src/main/java/org/sunflow/core/parser/SCAbstractParser.java +299 -0
  136. data/src/main/java/org/sunflow/core/parser/SCAsciiParser.java +251 -0
  137. data/src/main/java/org/sunflow/core/parser/SCBinaryParser.java +156 -0
  138. data/src/main/java/org/sunflow/core/parser/SCParser.java +1403 -0
  139. data/src/main/java/org/sunflow/core/parser/ShaveRibParser.java +174 -0
  140. data/src/main/java/org/sunflow/core/parser/TriParser.java +79 -0
  141. data/src/main/java/org/sunflow/core/photonmap/CausticPhotonMap.java +429 -0
  142. data/src/main/java/org/sunflow/core/photonmap/GlobalPhotonMap.java +530 -0
  143. data/src/main/java/org/sunflow/core/photonmap/GridPhotonMap.java +308 -0
  144. data/src/main/java/org/sunflow/core/primitive/Background.java +55 -0
  145. data/src/main/java/org/sunflow/core/primitive/BanchoffSurface.java +100 -0
  146. data/src/main/java/org/sunflow/core/primitive/Box.java +210 -0
  147. data/src/main/java/org/sunflow/core/primitive/CornellBox.java +476 -0
  148. data/src/main/java/org/sunflow/core/primitive/CubeGrid.java +318 -0
  149. data/src/main/java/org/sunflow/core/primitive/Cylinder.java +104 -0
  150. data/src/main/java/org/sunflow/core/primitive/Hair.java +275 -0
  151. data/src/main/java/org/sunflow/core/primitive/JuliaFractal.java +266 -0
  152. data/src/main/java/org/sunflow/core/primitive/ParticleSurface.java +114 -0
  153. data/src/main/java/org/sunflow/core/primitive/Plane.java +163 -0
  154. data/src/main/java/org/sunflow/core/primitive/QuadMesh.java +413 -0
  155. data/src/main/java/org/sunflow/core/primitive/Sphere.java +101 -0
  156. data/src/main/java/org/sunflow/core/primitive/SphereFlake.java +234 -0
  157. data/src/main/java/org/sunflow/core/primitive/Torus.java +145 -0
  158. data/src/main/java/org/sunflow/core/primitive/TriangleMesh.java +849 -0
  159. data/src/main/java/org/sunflow/core/renderer/BucketRenderer.java +491 -0
  160. data/src/main/java/org/sunflow/core/renderer/MultipassRenderer.java +237 -0
  161. data/src/main/java/org/sunflow/core/renderer/ProgressiveRenderer.java +171 -0
  162. data/src/main/java/org/sunflow/core/renderer/SimpleRenderer.java +106 -0
  163. data/src/main/java/org/sunflow/core/shader/AmbientOcclusionShader.java +53 -0
  164. data/src/main/java/org/sunflow/core/shader/AnisotropicWardShader.java +216 -0
  165. data/src/main/java/org/sunflow/core/shader/ConstantShader.java +31 -0
  166. data/src/main/java/org/sunflow/core/shader/DiffuseShader.java +65 -0
  167. data/src/main/java/org/sunflow/core/shader/GlassShader.java +147 -0
  168. data/src/main/java/org/sunflow/core/shader/IDShader.java +27 -0
  169. data/src/main/java/org/sunflow/core/shader/MirrorShader.java +68 -0
  170. data/src/main/java/org/sunflow/core/shader/NormalShader.java +32 -0
  171. data/src/main/java/org/sunflow/core/shader/PhongShader.java +89 -0
  172. data/src/main/java/org/sunflow/core/shader/PrimIDShader.java +30 -0
  173. data/src/main/java/org/sunflow/core/shader/QuickGrayShader.java +63 -0
  174. data/src/main/java/org/sunflow/core/shader/ShinyDiffuseShader.java +98 -0
  175. data/src/main/java/org/sunflow/core/shader/SimpleShader.java +24 -0
  176. data/src/main/java/org/sunflow/core/shader/TexturedAmbientOcclusionShader.java +31 -0
  177. data/src/main/java/org/sunflow/core/shader/TexturedDiffuseShader.java +31 -0
  178. data/src/main/java/org/sunflow/core/shader/TexturedPhongShader.java +31 -0
  179. data/src/main/java/org/sunflow/core/shader/TexturedShinyDiffuseShader.java +31 -0
  180. data/src/main/java/org/sunflow/core/shader/TexturedWardShader.java +31 -0
  181. data/src/main/java/org/sunflow/core/shader/UVShader.java +27 -0
  182. data/src/main/java/org/sunflow/core/shader/UberShader.java +149 -0
  183. data/src/main/java/org/sunflow/core/shader/ViewCausticsShader.java +33 -0
  184. data/src/main/java/org/sunflow/core/shader/ViewGlobalPhotonsShader.java +25 -0
  185. data/src/main/java/org/sunflow/core/shader/ViewIrradianceShader.java +25 -0
  186. data/src/main/java/org/sunflow/core/shader/WireframeShader.java +83 -0
  187. data/src/main/java/org/sunflow/core/tesselatable/BezierMesh.java +254 -0
  188. data/src/main/java/org/sunflow/core/tesselatable/FileMesh.java +251 -0
  189. data/src/main/java/org/sunflow/core/tesselatable/Gumbo.java +1147 -0
  190. data/src/main/java/org/sunflow/core/tesselatable/Teapot.java +237 -0
  191. data/src/main/java/org/sunflow/image/Bitmap.java +15 -0
  192. data/src/main/java/org/sunflow/image/BitmapReader.java +39 -0
  193. data/src/main/java/org/sunflow/image/BitmapWriter.java +79 -0
  194. data/src/main/java/org/sunflow/image/BlackbodySpectrum.java +16 -0
  195. data/src/main/java/org/sunflow/image/ChromaticitySpectrum.java +55 -0
  196. data/src/main/java/org/sunflow/image/Color.java +374 -0
  197. data/src/main/java/org/sunflow/image/ColorEncoder.java +94 -0
  198. data/src/main/java/org/sunflow/image/ColorFactory.java +122 -0
  199. data/src/main/java/org/sunflow/image/ConstantSpectralCurve.java +21 -0
  200. data/src/main/java/org/sunflow/image/IrregularSpectralCurve.java +57 -0
  201. data/src/main/java/org/sunflow/image/RGBSpace.java +207 -0
  202. data/src/main/java/org/sunflow/image/RegularSpectralCurve.java +30 -0
  203. data/src/main/java/org/sunflow/image/SpectralCurve.java +118 -0
  204. data/src/main/java/org/sunflow/image/XYZColor.java +50 -0
  205. data/src/main/java/org/sunflow/image/formats/BitmapBlack.java +27 -0
  206. data/src/main/java/org/sunflow/image/formats/BitmapG8.java +36 -0
  207. data/src/main/java/org/sunflow/image/formats/BitmapGA8.java +30 -0
  208. data/src/main/java/org/sunflow/image/formats/BitmapRGB8.java +40 -0
  209. data/src/main/java/org/sunflow/image/formats/BitmapRGBA8.java +40 -0
  210. data/src/main/java/org/sunflow/image/formats/BitmapRGBE.java +60 -0
  211. data/src/main/java/org/sunflow/image/formats/BitmapXYZ.java +38 -0
  212. data/src/main/java/org/sunflow/image/formats/GenericBitmap.java +73 -0
  213. data/src/main/java/org/sunflow/image/readers/BMPBitmapReader.java +39 -0
  214. data/src/main/java/org/sunflow/image/readers/HDRBitmapReader.java +155 -0
  215. data/src/main/java/org/sunflow/image/readers/IGIBitmapReader.java +104 -0
  216. data/src/main/java/org/sunflow/image/readers/JPGBitmapReader.java +39 -0
  217. data/src/main/java/org/sunflow/image/readers/PNGBitmapReader.java +40 -0
  218. data/src/main/java/org/sunflow/image/readers/TGABitmapReader.java +141 -0
  219. data/src/main/java/org/sunflow/image/writers/EXRBitmapWriter.java +395 -0
  220. data/src/main/java/org/sunflow/image/writers/HDRBitmapWriter.java +54 -0
  221. data/src/main/java/org/sunflow/image/writers/IGIBitmapWriter.java +75 -0
  222. data/src/main/java/org/sunflow/image/writers/PNGBitmapWriter.java +39 -0
  223. data/src/main/java/org/sunflow/image/writers/TGABitmapWriter.java +63 -0
  224. data/src/main/java/org/sunflow/math/BoundingBox.java +340 -0
  225. data/src/main/java/org/sunflow/math/MathUtils.java +159 -0
  226. data/src/main/java/org/sunflow/math/Matrix4.java +573 -0
  227. data/src/main/java/org/sunflow/math/MovingMatrix4.java +119 -0
  228. data/src/main/java/org/sunflow/math/OrthoNormalBasis.java +110 -0
  229. data/src/main/java/org/sunflow/math/PerlinScalar.java +331 -0
  230. data/src/main/java/org/sunflow/math/PerlinVector.java +132 -0
  231. data/src/main/java/org/sunflow/math/Point2.java +36 -0
  232. data/src/main/java/org/sunflow/math/Point3.java +133 -0
  233. data/src/main/java/org/sunflow/math/QMC.java +209 -0
  234. data/src/main/java/org/sunflow/math/Solvers.java +142 -0
  235. data/src/main/java/org/sunflow/math/Vector3.java +197 -0
  236. data/src/main/java/org/sunflow/system/BenchmarkFramework.java +73 -0
  237. data/src/main/java/org/sunflow/system/BenchmarkTest.java +17 -0
  238. data/src/main/java/org/sunflow/system/ByteUtil.java +119 -0
  239. data/src/main/java/org/sunflow/system/FileUtils.java +27 -0
  240. data/src/main/java/org/sunflow/system/ImagePanel.java +282 -0
  241. data/src/main/java/org/sunflow/system/Memory.java +18 -0
  242. data/src/main/java/org/sunflow/system/Parser.java +162 -0
  243. data/src/main/java/org/sunflow/system/Plugins.java +142 -0
  244. data/src/main/java/org/sunflow/system/RenderGlobalsPanel.java +209 -0
  245. data/src/main/java/org/sunflow/system/SearchPath.java +67 -0
  246. data/src/main/java/org/sunflow/system/Timer.java +53 -0
  247. data/src/main/java/org/sunflow/system/UI.java +112 -0
  248. data/src/main/java/org/sunflow/system/UserInterface.java +46 -0
  249. data/src/main/java/org/sunflow/system/ui/ConsoleInterface.java +48 -0
  250. data/src/main/java/org/sunflow/system/ui/SilentInterface.java +28 -0
  251. data/src/main/java/org/sunflow/util/FastHashMap.java +220 -0
  252. data/src/main/java/org/sunflow/util/FloatArray.java +77 -0
  253. data/src/main/java/org/sunflow/util/IntArray.java +77 -0
  254. data/src/test/java/a_maintest.java +129 -0
  255. metadata +300 -0
@@ -0,0 +1,98 @@
1
+ package org.sunflow;
2
+
3
+ import java.io.BufferedOutputStream;
4
+ import java.io.FileOutputStream;
5
+ import java.io.IOException;
6
+ import java.io.OutputStream;
7
+ import java.util.Locale;
8
+
9
+ import org.sunflow.core.ParameterList.InterpolationType;
10
+ import org.sunflow.core.parser.Keyword;
11
+ import org.sunflow.math.Matrix4;
12
+
13
+ class AsciiFileSunflowAPI extends FileSunflowAPI {
14
+
15
+ private OutputStream stream;
16
+
17
+ AsciiFileSunflowAPI(String filename) throws IOException {
18
+ stream = new BufferedOutputStream(new FileOutputStream(filename));
19
+ }
20
+
21
+ @Override
22
+ protected void writeBoolean(boolean value) {
23
+ if (value) {
24
+ writeString("true");
25
+ } else {
26
+ writeString("false");
27
+ }
28
+ }
29
+
30
+ @Override
31
+ protected void writeFloat(float value) {
32
+ writeString(String.format("%s", value));
33
+ }
34
+
35
+ @Override
36
+ protected void writeInt(int value) {
37
+ writeString(String.format("%d", value));
38
+ }
39
+
40
+ @Override
41
+ protected void writeInterpolationType(InterpolationType interp) {
42
+ writeString(String.format("%s", interp.toString().toLowerCase(Locale.ENGLISH)));
43
+ }
44
+
45
+ @Override
46
+ protected void writeKeyword(Keyword keyword) {
47
+ writeString(String.format("%s", keyword.toString().toLowerCase(Locale.ENGLISH).replace("_array", "[]")));
48
+ }
49
+
50
+ @Override
51
+ protected void writeMatrix(Matrix4 value) {
52
+ writeString("row");
53
+ for (float f : value.asRowMajor()) {
54
+ writeFloat(f);
55
+ }
56
+ }
57
+
58
+ @Override
59
+ protected void writeNewline(int indentNext) {
60
+ try {
61
+ stream.write('\n');
62
+ for (int i = 0; i < indentNext; i++) {
63
+ stream.write('\t');
64
+ }
65
+ } catch (IOException e) {
66
+ throw new RuntimeException(e.getMessage());
67
+ }
68
+ }
69
+
70
+ @Override
71
+ protected void writeString(String string) {
72
+ try {
73
+ // check if we need to write string with quotes
74
+ if (string.contains(" ") && !string.contains("<code>")) {
75
+ stream.write(String.format("\"%s\"", string).getBytes());
76
+ } else {
77
+ stream.write(string.getBytes());
78
+ }
79
+ stream.write(' ');
80
+ } catch (IOException e) {
81
+ throw new RuntimeException(e.getMessage());
82
+ }
83
+ }
84
+
85
+ @Override
86
+ protected void writeVerbatimString(String string) {
87
+ writeString(String.format("<code>%s\n</code> ", string));
88
+ }
89
+
90
+ @Override
91
+ public void close() {
92
+ try {
93
+ stream.close();
94
+ } catch (IOException e) {
95
+ throw new RuntimeException(e.getMessage());
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,313 @@
1
+ package org.sunflow;
2
+
3
+ import java.awt.image.BufferedImage;
4
+ import java.io.IOException;
5
+ import java.net.URL;
6
+
7
+ import javax.imageio.ImageIO;
8
+
9
+ import org.sunflow.core.Display;
10
+ import org.sunflow.core.display.FileDisplay;
11
+ import org.sunflow.core.display.FrameDisplay;
12
+ import org.sunflow.image.Color;
13
+ import org.sunflow.math.Matrix4;
14
+ import org.sunflow.math.Point3;
15
+ import org.sunflow.math.Vector3;
16
+ import org.sunflow.system.BenchmarkFramework;
17
+ import org.sunflow.system.BenchmarkTest;
18
+ import org.sunflow.system.UI;
19
+ import org.sunflow.system.UserInterface;
20
+ import org.sunflow.system.UI.Module;
21
+ import org.sunflow.system.UI.PrintLevel;
22
+
23
+ public class Benchmark implements BenchmarkTest, UserInterface, Display {
24
+
25
+ private int resolution;
26
+ private boolean showOutput;
27
+ private boolean showBenchmarkOutput;
28
+ private boolean saveOutput;
29
+ private boolean showWindow;
30
+ private int threads;
31
+ private int[] referenceImage;
32
+ private int[] validationImage;
33
+ private int errorThreshold;
34
+ final String DIFFUSE = "diffuse";
35
+ final String TRANSFORM = "transform";
36
+ final String TEAPOT = "teapot";
37
+
38
+ public static void main(String[] args) {
39
+ if (args.length == 0) {
40
+ System.out.println("Benchmark options:");
41
+ System.out.println(" -regen Regenerate reference images for a variety of sizes");
42
+ System.out.println(" -bench [threads] [resolution] Run a single iteration of the benchmark using the specified thread count and image resolution");
43
+ System.out.println(" Default: threads=0 (auto-detect cpus), resolution=256");
44
+ System.out.println(" -show Render the benchmark scene into a window without performing validation");
45
+ } else if (args[0].equals("-regen")) {
46
+ int[] sizes = {32, 64, 96, 128, 256, 384, 512};
47
+ for (int s : sizes) {
48
+ // run a single iteration to generate the reference image
49
+ Benchmark b = new Benchmark(s, true, false, true);
50
+ b.kernelMain();
51
+ }
52
+ } else if (args[0].equals("-bench")) {
53
+ int threads = 0, resolution = 256;
54
+ if (args.length > 1) {
55
+ threads = Integer.parseInt(args[1]);
56
+ }
57
+ if (args.length > 2) {
58
+ resolution = Integer.parseInt(args[2]);
59
+ }
60
+ Benchmark benchmark = new Benchmark(resolution, false, true, false, threads, false);
61
+ benchmark.kernelBegin();
62
+ benchmark.kernelMain();
63
+ benchmark.kernelEnd();
64
+ } else if (args[0].equals("-show")) {
65
+ Benchmark benchmark = new Benchmark(512, true, true, false, 0, true);
66
+ benchmark.kernelMain();
67
+ }
68
+ }
69
+
70
+ public Benchmark() {
71
+ this(384, false, true, false);
72
+ }
73
+
74
+ public Benchmark(int resolution, boolean showOutput, boolean showBenchmarkOutput, boolean saveOutput) {
75
+ this(resolution, showOutput, showBenchmarkOutput, saveOutput, 0, false);
76
+ }
77
+
78
+ public Benchmark(int resolution, boolean showOutput, boolean showBenchmarkOutput, boolean saveOutput, int threads, boolean showWindow) {
79
+ UI.set(this);
80
+ this.resolution = resolution;
81
+ this.showOutput = showOutput;
82
+ this.showBenchmarkOutput = showBenchmarkOutput;
83
+ this.saveOutput = saveOutput;
84
+ this.showWindow = showWindow;
85
+ this.threads = threads;
86
+ errorThreshold = 6;
87
+ // fetch reference image from resources (jar file or classpath)
88
+ if (saveOutput) {
89
+ return;
90
+ }
91
+ URL imageURL = Benchmark.class.getResource(String.format("/resources/golden_%04X.png", resolution));
92
+ if (imageURL == null) {
93
+ UI.printError(Module.BENCH, "Unable to find reference frame!");
94
+ }
95
+ UI.printInfo(Module.BENCH, "Loading reference image from: %s", imageURL);
96
+ try {
97
+ BufferedImage bi = ImageIO.read(imageURL);
98
+ if (bi.getWidth() != resolution || bi.getHeight() != resolution) {
99
+ UI.printError(Module.BENCH, "Reference image has invalid resolution! Expected %dx%d found %dx%d", resolution, resolution, bi.getWidth(), bi.getHeight());
100
+ }
101
+ referenceImage = new int[resolution * resolution];
102
+ for (int y = 0, i = 0; y < resolution; y++) {
103
+ for (int x = 0; x < resolution; x++, i++) {
104
+ referenceImage[i] = bi.getRGB(x, resolution - 1 - y); // flip
105
+ }
106
+ }
107
+ } catch (IOException e) {
108
+ UI.printError(Module.BENCH, "Unable to load reference frame!");
109
+ }
110
+ }
111
+
112
+ public void execute() {
113
+ // 10 iterations maximum - 10 minute time limit
114
+ BenchmarkFramework framework = new BenchmarkFramework(10, 600);
115
+ framework.execute(this);
116
+ }
117
+
118
+ private class BenchmarkScene extends SunflowAPI {
119
+
120
+ final String GRAY_SHADER = "gray_shader";
121
+ final String SHADERS = "shaders";
122
+
123
+ public BenchmarkScene() {
124
+ build();
125
+ render(SunflowAPI.DEFAULT_OPTIONS, showWindow ? new FrameDisplay() : saveOutput ? new FileDisplay(String.format("resources/golden_%04X.png", resolution)) : Benchmark.this);
126
+ }
127
+
128
+ @Override
129
+ public final void build() {
130
+ // settings
131
+ parameter("threads", threads);
132
+ // spawn regular priority threads
133
+ parameter("threads.lowPriority", false);
134
+ parameter("resolutionX", resolution);
135
+ parameter("resolutionY", resolution);
136
+ parameter("aa.min", -1);
137
+ parameter("aa.max", 1);
138
+ parameter("filter", "triangle");
139
+ parameter("depths.diffuse", 2);
140
+ parameter("depths.reflection", 2);
141
+ parameter("depths.refraction", 2);
142
+ parameter("bucket.order", "hilbert");
143
+ parameter("bucket.size", 32);
144
+ // gi options
145
+ parameter("gi.engine", "igi");
146
+ parameter("gi.igi.samples", 90);
147
+ parameter("gi.igi.c", 0.000008f);
148
+ options(SunflowAPI.DEFAULT_OPTIONS);
149
+ buildCornellBox();
150
+ }
151
+
152
+ private void buildCornellBox() {
153
+ // camera
154
+ parameter(TRANSFORM, Matrix4.lookAt(new Point3(0, 0, -600), new Point3(0, 0, 0), new Vector3(0, 1, 0)));
155
+ parameter("fov", 45.0f);
156
+ camera("main_camera", "pinhole");
157
+ parameter("camera", "main_camera");
158
+ options(SunflowAPI.DEFAULT_OPTIONS);
159
+ // cornell box
160
+ float minX = -200;
161
+ float maxX = 200;
162
+ float minY = -160;
163
+ float maxY = minY + 400;
164
+ float minZ = -250;
165
+ float maxZ = 200;
166
+
167
+ float[] verts = new float[]{minX, minY, minZ, maxX, minY, minZ,
168
+ maxX, minY, maxZ, minX, minY, maxZ, minX, maxY, minZ, maxX,
169
+ maxY, minZ, maxX, maxY, maxZ, minX, maxY, maxZ,};
170
+ int[] indices = new int[]{0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 1,
171
+ 2, 5, 5, 6, 2, 2, 3, 6, 6, 7, 3, 0, 3, 4, 4, 7, 3};
172
+
173
+ parameter(DIFFUSE, null, 0.70f, 0.70f, 0.70f);
174
+ shader(GRAY_SHADER, DIFFUSE);
175
+ parameter(DIFFUSE, null, 0.80f, 0.25f, 0.25f);
176
+ shader("red_shader", DIFFUSE);
177
+ parameter(DIFFUSE, null, 0.25f, 0.25f, 0.80f);
178
+ shader("blue_shader", DIFFUSE);
179
+
180
+ // build walls
181
+ parameter("triangles", indices);
182
+ parameter("points", "point", "vertex", verts);
183
+ parameter("faceshaders", new int[]{0, 0, 0, 0, 1, 1, 0, 0, 2, 2});
184
+ geometry("walls", "triangle_mesh");
185
+
186
+ // instance walls
187
+ parameter(SHADERS, new String[]{GRAY_SHADER, "red_shader",
188
+ "blue_shader"});
189
+ instance("walls.instance", "walls");
190
+
191
+ // create mesh light
192
+ parameter("points", "point", "vertex", new float[]{-50, maxY - 1,
193
+ -50, 50, maxY - 1, -50, 50, maxY - 1, 50, -50, maxY - 1, 50});
194
+ parameter("triangles", new int[]{0, 1, 2, 2, 3, 0});
195
+ parameter("radiance", null, 15, 15, 15);
196
+ parameter("samples", 8);
197
+ light("light", "triangle_mesh");
198
+
199
+ // spheres
200
+ parameter("eta", 1.6f);
201
+ shader("Glass", "glass");
202
+ sphere("glass_sphere", "Glass", -120, minY + 55, -150, 50);
203
+ parameter("color", null, 0.70f, 0.70f, 0.70f);
204
+ shader("Mirror", "mirror");
205
+ sphere("mirror_sphere", "Mirror", 100, minY + 60, -50, 50);
206
+
207
+ // scanned model
208
+ geometry(TEAPOT, TEAPOT);
209
+ parameter(TRANSFORM, Matrix4.translation(80, -50, 100).multiply(Matrix4.rotateX((float) -Math.PI / 6)).multiply(Matrix4.rotateY((float) Math.PI / 4)).multiply(Matrix4.rotateX((float) -Math.PI / 2).multiply(Matrix4.scale(1.2f))));
210
+ parameter(SHADERS, GRAY_SHADER);
211
+ instance("teapot.instance1", TEAPOT);
212
+ parameter(TRANSFORM, Matrix4.translation(-80, -160, 50).multiply(Matrix4.rotateY((float) Math.PI / 4)).multiply(Matrix4.rotateX((float) -Math.PI / 2).multiply(Matrix4.scale(1.2f))));
213
+ parameter(SHADERS, GRAY_SHADER);
214
+ instance("teapot.instance2", TEAPOT);
215
+ }
216
+
217
+ private void sphere(String name, String shaderName, float x, float y, float z, float radius) {
218
+ geometry(name, "sphere");
219
+ parameter(TRANSFORM, Matrix4.translation(x, y, z).multiply(Matrix4.scale(radius)));
220
+ parameter(SHADERS, shaderName);
221
+ instance(name + ".instance", name);
222
+ }
223
+ }
224
+
225
+ @Override
226
+ public void kernelBegin() {
227
+ // allocate a fresh validation target
228
+ validationImage = new int[resolution * resolution];
229
+ }
230
+
231
+ @Override
232
+ public void kernelMain() {
233
+ // this builds and renders the scene
234
+ new BenchmarkScene();
235
+ }
236
+
237
+ @Override
238
+ public void kernelEnd() {
239
+ // make sure the rendered image was correct
240
+ int diff = 0;
241
+ if (referenceImage != null && validationImage.length == referenceImage.length) {
242
+ for (int i = 0; i < validationImage.length; i++) {
243
+ // count absolute RGB differences
244
+ diff += Math.abs((validationImage[i] & 0xFF) - (referenceImage[i] & 0xFF));
245
+ diff += Math.abs(((validationImage[i] >> 8) & 0xFF) - ((referenceImage[i] >> 8) & 0xFF));
246
+ diff += Math.abs(((validationImage[i] >> 16) & 0xFF) - ((referenceImage[i] >> 16) & 0xFF));
247
+ }
248
+ if (diff > errorThreshold) {
249
+ UI.printError(Module.BENCH, "Image check failed! - #errors: %d", diff);
250
+ } else {
251
+ UI.printInfo(Module.BENCH, "Image check passed!");
252
+ }
253
+ } else {
254
+ UI.printError(Module.BENCH, "Image check failed! - reference is not comparable");
255
+ }
256
+
257
+ }
258
+
259
+ @Override
260
+ public void print(Module m, PrintLevel level, String s) {
261
+ if (showOutput || (showBenchmarkOutput && m == Module.BENCH)) {
262
+ System.out.println(UI.formatOutput(m, level, s));
263
+ }
264
+ if (level == PrintLevel.ERROR) {
265
+ throw new RuntimeException(s);
266
+ }
267
+ }
268
+
269
+ @Override
270
+ public void taskStart(String s, int min, int max) {
271
+ // render progress display not needed
272
+ }
273
+
274
+ @Override
275
+ public void taskStop() {
276
+ // render progress display not needed
277
+ }
278
+
279
+ @Override
280
+ public void taskUpdate(int current) {
281
+ // render progress display not needed
282
+ }
283
+
284
+ @Override
285
+ public void imageBegin(int w, int h, int bucketSize) {
286
+ // we can assume w == h == resolution
287
+ }
288
+
289
+ @Override
290
+ public void imageEnd() {
291
+ // nothing needs to be done - image verification is done externally
292
+ }
293
+
294
+ @Override
295
+ public void imageFill(int x, int y, int w, int h, Color c, float alpha) {
296
+ // this is not used
297
+ }
298
+
299
+ @Override
300
+ public void imagePrepare(int x, int y, int w, int h, int id) {
301
+ // this is not needed
302
+ }
303
+
304
+ @Override
305
+ public void imageUpdate(int x, int y, int w, int h, Color[] data, float[] alpha) {
306
+ // copy bucket data to validation image
307
+ for (int j = 0, index = 0; j < h; j++, y++) {
308
+ for (int i = 0, offset = x + resolution * (resolution - 1 - y); i < w; i++, index++, offset++) {
309
+ validationImage[offset] = data[index].copy().toNonLinear().toRGB();
310
+ }
311
+ }
312
+ }
313
+ }
@@ -0,0 +1,228 @@
1
+ package org.sunflow;
2
+
3
+ import java.io.BufferedOutputStream;
4
+ import java.io.DataOutputStream;
5
+ import java.io.FileNotFoundException;
6
+ import java.io.FileOutputStream;
7
+ import java.io.IOException;
8
+
9
+ import org.sunflow.core.ParameterList.InterpolationType;
10
+ import org.sunflow.core.parser.Keyword;
11
+ import org.sunflow.math.Matrix4;
12
+
13
+ class BinaryFileSunflowAPI extends FileSunflowAPI {
14
+
15
+ private DataOutputStream stream;
16
+
17
+ BinaryFileSunflowAPI(String filename) throws FileNotFoundException {
18
+ stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
19
+ }
20
+
21
+ @Override
22
+ protected void writeBoolean(boolean value) {
23
+ try {
24
+ if (value) {
25
+ stream.write(1);
26
+ } else {
27
+ stream.write(0);
28
+ }
29
+ } catch (IOException e) {
30
+ // throw as a silent exception to avoid having to propage throw
31
+ // declarations upwards
32
+ throw new RuntimeException(e.getMessage());
33
+ }
34
+ }
35
+
36
+ @Override
37
+ protected void writeFloat(float value) {
38
+ writeInt(Float.floatToRawIntBits(value));
39
+ }
40
+
41
+ @Override
42
+ protected void writeInt(int value) {
43
+ try {
44
+ // little endian, LSB first
45
+ stream.write(value & 0xFF);
46
+ stream.write((value >>> 8) & 0xFF);
47
+ stream.write((value >>> 16) & 0xFF);
48
+ stream.write((value >>> 24) & 0xFF);
49
+ } catch (IOException e) {
50
+ throw new RuntimeException(e.getMessage());
51
+ }
52
+ }
53
+
54
+ @Override
55
+ protected void writeInterpolationType(InterpolationType interp) {
56
+ try {
57
+ switch (interp) {
58
+ case NONE:
59
+ stream.write('n');
60
+ break;
61
+ case VERTEX:
62
+ stream.write('v');
63
+ break;
64
+ case FACE:
65
+ stream.write('p');
66
+ break;
67
+ case FACEVARYING:
68
+ stream.write('f');
69
+ break;
70
+ default:
71
+ throw new RuntimeException(String.format("Unknown interpolation type \"%s\"", interp.toString()));
72
+ }
73
+ } catch (IOException e) {
74
+ throw new RuntimeException(e.getMessage());
75
+ }
76
+ }
77
+
78
+ @Override
79
+ protected void writeKeyword(Keyword keyword) {
80
+ try {
81
+ switch (keyword) {
82
+ case RESET:
83
+ writeExtendedKeyword('R');
84
+ break;
85
+ case PARAMETER:
86
+ stream.write('p');
87
+ break;
88
+ case GEOMETRY:
89
+ stream.write('g');
90
+ break;
91
+ case INSTANCE:
92
+ stream.write('i');
93
+ break;
94
+ case SHADER:
95
+ stream.write('s');
96
+ break;
97
+ case MODIFIER:
98
+ stream.write('m');
99
+ break;
100
+ case LIGHT:
101
+ stream.write('l');
102
+ break;
103
+ case CAMERA:
104
+ stream.write('c');
105
+ break;
106
+ case OPTIONS:
107
+ stream.write('o');
108
+ break;
109
+ case INCLUDE:
110
+ writeExtendedKeyword('i');
111
+ break;
112
+ case REMOVE:
113
+ writeExtendedKeyword('r');
114
+ break;
115
+ case FRAME:
116
+ writeExtendedKeyword('f');
117
+ break;
118
+ case PLUGIN:
119
+ writeExtendedKeyword('p');
120
+ break;
121
+ case SEARCHPATH:
122
+ writeExtendedKeyword('s');
123
+ break;
124
+ case STRING:
125
+ writeDatatypeKeyword('s', false);
126
+ break;
127
+ case BOOL:
128
+ writeDatatypeKeyword('b', false);
129
+ break;
130
+ case INT:
131
+ writeDatatypeKeyword('i', false);
132
+ break;
133
+ case FLOAT:
134
+ writeDatatypeKeyword('f', false);
135
+ break;
136
+ case COLOR:
137
+ writeDatatypeKeyword('c', false);
138
+ break;
139
+ case POINT:
140
+ writeDatatypeKeyword('p', false);
141
+ break;
142
+ case VECTOR:
143
+ writeDatatypeKeyword('v', false);
144
+ break;
145
+ case TEXCOORD:
146
+ writeDatatypeKeyword('t', false);
147
+ break;
148
+ case MATRIX:
149
+ writeDatatypeKeyword('m', false);
150
+ break;
151
+ case STRING_ARRAY:
152
+ writeDatatypeKeyword('s', true);
153
+ break;
154
+ case INT_ARRAY:
155
+ writeDatatypeKeyword('i', true);
156
+ break;
157
+ case FLOAT_ARRAY:
158
+ writeDatatypeKeyword('f', true);
159
+ break;
160
+ case POINT_ARRAY:
161
+ writeDatatypeKeyword('p', true);
162
+ break;
163
+ case VECTOR_ARRAY:
164
+ writeDatatypeKeyword('v', true);
165
+ break;
166
+ case TEXCOORD_ARRAY:
167
+ writeDatatypeKeyword('t', true);
168
+ break;
169
+ case MATRIX_ARRAY:
170
+ writeDatatypeKeyword('m', true);
171
+ break;
172
+ default:
173
+ throw new RuntimeException(String.format("Unknown keyword \"%s\" requested", keyword.toString()));
174
+ }
175
+ } catch (IOException e) {
176
+ throw new RuntimeException(e.getMessage());
177
+ }
178
+ }
179
+
180
+ private void writeExtendedKeyword(int code) throws IOException {
181
+ stream.write('x');
182
+ stream.write(code);
183
+ }
184
+
185
+ // helper routine for datatype keywords
186
+ private void writeDatatypeKeyword(int type, boolean isArray) throws IOException {
187
+ stream.write('t');
188
+ stream.write(type);
189
+ writeBoolean(isArray);
190
+ }
191
+
192
+ @Override
193
+ protected void writeMatrix(Matrix4 value) {
194
+ for (float f : value.asRowMajor()) {
195
+ writeFloat(f);
196
+ }
197
+ }
198
+
199
+ @Override
200
+ protected void writeString(String string) {
201
+ try {
202
+ byte[] data = string.getBytes("UTF-8");
203
+ writeInt(data.length);
204
+ stream.write(data);
205
+ } catch (Exception e) {
206
+ throw new RuntimeException(e.getMessage());
207
+ }
208
+ }
209
+
210
+ @Override
211
+ protected void writeVerbatimString(String string) {
212
+ writeString(string);
213
+ }
214
+
215
+ @Override
216
+ protected void writeNewline(int indentNext) {
217
+ // does nothing
218
+ }
219
+
220
+ @Override
221
+ public void close() {
222
+ try {
223
+ stream.close();
224
+ } catch (IOException e) {
225
+ throw new RuntimeException(e.getMessage());
226
+ }
227
+ }
228
+ }