Skip to content

Commit 40084d7

Browse files
committed
Working on description of OpenGL program
1 parent ffb4b1a commit 40084d7

1 file changed

Lines changed: 35 additions & 29 deletions

File tree

src/volumetric_clouds/main.clj

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@
624624
;; #### OpenGL setup
625625
;;
626626
;; In order to render the clouds we create a window and an OpenGL context.
627+
;; Note that we need to create an invisible window to get an OpenGL context, even though we are not going to draw to the window
627628
(GLFW/glfwInit)
628629

629630
(def window-width 640)
@@ -647,7 +648,7 @@
647648
(throw (Exception. (GL20/glGetShaderInfoLog shader 1024))))
648649
shader))
649650

650-
651+
;; The different shaders are then linked to become a shader program using the following method.
651652
(defn make-program [& shaders]
652653
(let [program (GL20/glCreateProgram)]
653654
(doseq [shader shaders]
@@ -658,24 +659,24 @@
658659
(throw (Exception. (GL20/glGetProgramInfoLog program 1024))))
659660
program))
660661

661-
662+
;; This method is used to perform both compilation and linking of vertex shaders and fragment shaders.
662663
(defn make-program-with-shaders
663664
[vertex-sources fragment-sources]
664665
(let [vertex-shaders (map #(make-shader % GL20/GL_VERTEX_SHADER) vertex-sources)
665666
fragment-shaders (map #(make-shader % GL20/GL_FRAGMENT_SHADER) fragment-sources)
666667
program (apply make-program (concat vertex-shaders fragment-shaders))]
667668
program))
668669

669-
670-
(def vertex-test
670+
;; We are going to use this simple vertex shader to simply pass a vertex through without any transformations.
671+
(def vertex-passthrough
671672
"#version 130
672673
in vec3 point;
673674
void main()
674675
{
675676
gl_Position = vec4(point, 1);
676677
}")
677678

678-
679+
;; The following fragment shader is used to test rendering white pixels.
679680
(def fragment-test
680681
"#version 130
681682
out vec4 fragColor;
@@ -684,18 +685,20 @@ void main()
684685
fragColor = vec4(1, 1, 1, 1);
685686
}")
686687

687-
688+
;; In order to pass data to LWJGL methods, we need to be able to convert arrays to Java buffer objects.
688689
(defmacro def-make-buffer [method create-buffer]
689690
`(defn ~method [data#]
690691
(let [buffer# (~create-buffer (count data#))]
691692
(.put buffer# data#)
692693
(.flip buffer#)
693694
buffer#)))
694695

696+
;; Above macro is used to define methods for creating float, int, and byte buffer objects.
695697
(def-make-buffer make-float-buffer BufferUtils/createFloatBuffer)
696698
(def-make-buffer make-int-buffer BufferUtils/createIntBuffer)
697699
(def-make-buffer make-byte-buffer BufferUtils/createByteBuffer)
698700

701+
;; We implement a method to create a vertex array object with a vertex buffer object and an index buffer object.
699702
(defn setup-vao [vertices indices]
700703
(let [vao (GL30/glGenVertexArrays)
701704
vbo (GL15/glGenBuffers)
@@ -709,7 +712,7 @@ void main()
709712
GL15/GL_STATIC_DRAW)
710713
{:vao vao :vbo vbo :ibo ibo}))
711714

712-
715+
;; We also define the corresponding destructor for the vertex data.
713716
(defn teardown-vao [{:keys [vao vbo ibo]}]
714717
(GL15/glBindBuffer GL15/GL_ELEMENT_ARRAY_BUFFER 0)
715718
(GL15/glDeleteBuffers ibo)
@@ -718,16 +721,9 @@ void main()
718721
(GL30/glBindVertexArray 0)
719722
(GL15/glDeleteBuffers vao))
720723

721-
722-
(defn float-buffer->array
723-
"Convert float buffer to flaot array"
724-
[buffer]
725-
(let [result (float-array (.limit buffer))]
726-
(.get buffer result)
727-
(.flip buffer)
728-
result))
729-
730-
724+
;; #### Offscreen rendering to a texture
725+
;;
726+
;; The following method is used to create an empty 2D RGBA floating point texture
731727
(defn make-texture-2d
732728
[width height]
733729
(let [texture (GL11/glGenTextures)]
@@ -739,15 +735,24 @@ void main()
739735
(GL42/glTexStorage2D GL11/GL_TEXTURE_2D 1 GL30/GL_RGBA32F width height)
740736
texture))
741737

738+
;; We define a method to convert a Java buffer object to a floating point array.
739+
(defn float-buffer->array
740+
"Convert float buffer to float array"
741+
[buffer]
742+
(let [result (float-array (.limit buffer))]
743+
(.get buffer result)
744+
(.flip buffer)
745+
result))
742746

747+
;; The following method reads texture data into a Java buffer and then converts it to a floating point array.
743748
(defn read-texture-2d
744749
[texture width height]
745750
(let [buffer (BufferUtils/createFloatBuffer (* height width 4))]
746751
(GL11/glBindTexture GL11/GL_TEXTURE_2D texture)
747752
(GL11/glGetTexImage GL11/GL_TEXTURE_2D 0 GL12/GL_RGBA GL11/GL_FLOAT buffer)
748753
(float-buffer->array buffer)))
749754

750-
755+
;; This method sets up rendering to a specified texture of specified size and then executes the body.
751756
(defmacro framebuffer-render
752757
[texture width height & body]
753758
`(let [fbo# (GL30/glGenFramebuffers)]
@@ -764,7 +769,8 @@ void main()
764769
(GL30/glBindFramebuffer GL30/GL_FRAMEBUFFER 0)
765770
(GL30/glDeleteFramebuffers fbo#)))))
766771

767-
772+
;; We also create a method to set up the layout of the vertex buffer.
773+
;; Our vertex data is only going to be 3D coordinates of points.
768774
(defn setup-point-attribute
769775
[program]
770776
(let [point-attribute (GL20/glGetAttribLocation program "point")]
@@ -804,7 +810,7 @@ void main()
804810
(GL20/glDeleteProgram program)))))
805811

806812

807-
(render-pixel [vertex-test] [fragment-test])
813+
(render-pixel [vertex-passthrough] [fragment-test])
808814

809815

810816
;; ## Noise octaves shader
@@ -830,7 +836,7 @@ void main()
830836

831837

832838
(tabular "Test noise mock"
833-
(fact (nth (render-pixel [vertex-test] [noise-mock (noise-probe ?x ?y ?z)]) 0)
839+
(fact (nth (render-pixel [vertex-passthrough] [noise-mock (noise-probe ?x ?y ?z)]) 0)
834840
=> ?result)
835841
?x ?y ?z ?result
836842
0 0 0 0.0
@@ -871,7 +877,7 @@ void main()
871877

872878

873879
(tabular "Test octaves of noise"
874-
(fact (first (render-pixel [vertex-test]
880+
(fact (first (render-pixel [vertex-passthrough]
875881
[noise-mock (noise-octaves ?octaves)
876882
(octaves-probe ?x ?y ?z)]))
877883
=> ?result)
@@ -921,7 +927,7 @@ void main()
921927

922928
(tabular "Test intersection of ray with box"
923929
(fact ((juxt first second)
924-
(render-pixel [vertex-test]
930+
(render-pixel [vertex-passthrough]
925931
[ray-box (ray-box-probe ?ox ?oy ?oz ?dx ?dy ?dz)]))
926932
=> ?result)
927933
?ox ?oy ?oz ?dx ?dy ?dz ?result
@@ -1010,7 +1016,7 @@ void main()
10101016

10111017

10121018
(tabular "Test cloud transfer"
1013-
(fact (seq (render-pixel [vertex-test]
1019+
(fact (seq (render-pixel [vertex-passthrough]
10141020
[(fog ?density) constant-scatter no-shadow
10151021
(cloud-transfer "fog" ?step)
10161022
(cloud-transfer-probe ?a ?b)]))
@@ -1065,7 +1071,7 @@ void main()
10651071
[width height]
10661072
(let [fragment-sources [ray-box constant-scatter no-shadow (cloud-transfer "fog" 0.01)
10671073
(fog 1.0) fragment-cloud]
1068-
program (make-program-with-shaders [vertex-test] fragment-sources)
1074+
program (make-program-with-shaders [vertex-passthrough] fragment-sources)
10691075
vao (setup-quad-vao)]
10701076
(setup-point-attribute program)
10711077
(try
@@ -1131,7 +1137,7 @@ float noise(vec3 idx)
11311137
(defn render-noise
11321138
[width height & cloud-shaders]
11331139
(let [fragment-sources (concat cloud-shaders [ray-box fragment-cloud])
1134-
program (make-program-with-shaders [vertex-test] fragment-sources)
1140+
program (make-program-with-shaders [vertex-passthrough] fragment-sources)
11351141
vao (setup-quad-vao)]
11361142
(try
11371143
(setup-point-attribute program)
@@ -1174,7 +1180,7 @@ void main()
11741180

11751181
(tabular "Remap and clamp input parameter values"
11761182
(fact (first (render-pixel
1177-
[vertex-test]
1183+
[vertex-passthrough]
11781184
[remap-clamp (remap-probe ?value ?low1 ?high1 ?low2 ?high2)]))
11791185
=> ?expected)
11801186
?value ?low1 ?high1 ?low2 ?high2 ?expected
@@ -1253,7 +1259,7 @@ void main()
12531259

12541260

12551261
(tabular "Shader function for scattering phase function"
1256-
(fact (first (render-pixel [vertex-test] [(mie-scatter ?g) (mie-probe ?mu)]))
1262+
(fact (first (render-pixel [vertex-passthrough] [(mie-scatter ?g) (mie-probe ?mu)]))
12571263
=> (roughly ?result 1e-6))
12581264
?g ?mu ?result
12591265
0 0 (/ 3 (* 16 PI))
@@ -1264,7 +1270,7 @@ void main()
12641270

12651271

12661272
(defn scatter-amount [theta]
1267-
(first (render-pixel [vertex-test] [(mie-scatter 0.76) (mie-probe (cos theta))])))
1273+
(first (render-pixel [vertex-passthrough] [(mie-scatter 0.76) (mie-probe (cos theta))])))
12681274

12691275

12701276
(let [scatter

0 commit comments

Comments
 (0)