diff --git a/dot-to-dot b/dot-to-dot index 82ca135..f308d67 100755 Binary files a/dot-to-dot and b/dot-to-dot differ diff --git a/dot-to-dot.mlb b/dot-to-dot.mlb index 9788f20..8b2a57d 100644 --- a/dot-to-dot.mlb +++ b/dot-to-dot.mlb @@ -23,8 +23,13 @@ ann "allowVectorExps true" in imperative-shell/constants.sml + imperative-shell/app-draw.sml end -imperative-shell/app-draw.sml imperative-shell/input-callbacks.sml -imperative-shell/shell.sml + +ann + "allowVectorExps true" +in + imperative-shell/shell.sml +end diff --git a/ffi/gles3-export.c b/ffi/gles3-export.c index c023d86..2e32429 100644 --- a/ffi/gles3-export.c +++ b/ffi/gles3-export.c @@ -58,8 +58,8 @@ void deleteShader(unsigned int shader) { glDeleteShader(shader); } -void vertexAttribPointer(int location, int numVecComponents) { - glVertexAttribPointer(location, numVecComponents, GL_FLOAT, GL_FALSE, numVecComponents * sizeof(float), (void*) 0); +void vertexAttribPointer(int location, int numVecComponents, int stride, int offset) { + glVertexAttribPointer(location, numVecComponents, GL_FLOAT, GL_FALSE, stride * sizeof(float), (void*)offset); } void enableVertexAttribArray(int location) { diff --git a/ffi/gles3-import.sml b/ffi/gles3-import.sml index 46932e2..d876cea 100644 --- a/ffi/gles3-import.sml +++ b/ffi/gles3-import.sml @@ -36,7 +36,7 @@ struct val shaderSource = _import "shaderSource" public : shader * string -> unit; val vertexAttribPointer = - _import "vertexAttribPointer" public : int * int -> unit; + _import "vertexAttribPointer" public : int * int * int * int -> unit; val enableVertexAttribArray = _import "enableVertexAttribArray" public : int -> unit; diff --git a/imperative-shell/app-draw.sml b/imperative-shell/app-draw.sml index bafdc20..5d3f86c 100644 --- a/imperative-shell/app-draw.sml +++ b/imperative-shell/app-draw.sml @@ -46,7 +46,7 @@ struct , Vector.length Constants.graphLines , Gles3.STATIC_DRAW () ) - val _ = Gles3.vertexAttribPointer (0, 2) + val _ = Gles3.vertexAttribPointer (0, 2, 2, 0) val _ = Gles3.enableVertexAttribArray 0 in graphDrawObject @@ -54,11 +54,70 @@ struct fun drawGraphLines (graphDrawObject: draw_object) = let - val {program, ...} = graphDrawObject - val _ = Gles3.useProgram (program) + val {vertexBuffer, program, ...} = graphDrawObject + val _ = Gles3.bindBuffer vertexBuffer + val _ = Gles3.vertexAttribPointer (0, 2, 2, 0) + val _ = Gles3.enableVertexAttribArray 0 + val _ = Gles3.useProgram program val _ = Gles3.drawArrays (Gles3.TRIANGLES (), 0, Vector.length Constants.graphLines div 2) in () end + + val buttonVec = + #[ 0.5, 0.5, 1.0, 0.0, 0.0 + , 0.5, ~0.5, 1.0, 0.0, 0.0 + , ~0.5, 0.5, 1.0, 0.0, 0.0 + + , 0.5, ~0.5, 0.0, 0.0, 1.0 + , ~0.5, ~0.5, 0.0, 0.0, 1.0 + , ~0.5, 0.5, 0.0, 0.0, 1.0 + ] + + fun initButton () = + let + val buttonDrawObject = initDrawObject + ( Constants.colouredVertexShaderString + , Constants.colouredFragmentShaderString + ) + val {vertexBuffer, program, ...} = buttonDrawObject + + val _ = Gles3.bindBuffer vertexBuffer + val _ = + Gles3.bufferData + (buttonVec, Vector.length buttonVec, Gles3.STATIC_DRAW ()) + val _ = Gles3.vertexAttribPointer (0, 2, 5, 0) + val _ = Gles3.enableVertexAttribArray 0 + + val _ = Gles3.vertexAttribPointer (1, 3, 5, 8) + val _ = Gles3.enableVertexAttribArray 1 + in + buttonDrawObject + end + + fun uploadButtonVector (buttonDrawObject: draw_object, vec) = + let + val {vertexBuffer, ...} = buttonDrawObject + val _ = Gles3.bindBuffer vertexBuffer + val _ = Gles3.bufferData (vec, Vector.length vec, Gles3.STATIC_DRAW ()) + in + () + end + + fun drawButton (buttonDrawObject: draw_object, vec) = + let + val {vertexBuffer, program, ...} = buttonDrawObject + val _ = Gles3.bindBuffer vertexBuffer + val _ = Gles3.vertexAttribPointer (0, 2, 5, 0) + val _ = Gles3.enableVertexAttribArray 0 + val _ = Gles3.vertexAttribPointer (1, 3, 5, 8) + val _ = Gles3.enableVertexAttribArray 1 + val _ = Gles3.useProgram program + val _ = Gles3.drawArrays + (Gles3.TRIANGLES (), 0, Vector.length buttonVec div 5) + in + () + end + end diff --git a/imperative-shell/constants.sml b/imperative-shell/constants.sml index 0068c1e..52f7eaa 100644 --- a/imperative-shell/constants.sml +++ b/imperative-shell/constants.sml @@ -17,6 +17,27 @@ struct \ FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n\ \}" + val colouredVertexShaderString = + "#version 300 es\n\ + \layout (location = 0) in vec2 apos;\n\ + \layout (location = 1) in vec3 col;\n\ + \out vec3 frag_col;\n\ + \void main()\n\ + \{\n\ + \ frag_col = col;\n\ + \ gl_Position = vec4(apos.x, apos.y, 0.0f, 1.0f);\n\ + \}" + + val colouredFragmentShaderString = + "#version 300 es\n\ + \precision mediump float;\n\ + \in vec3 frag_col;\n\ + \out vec4 FragColor;\n\ + \void main()\n\ + \{\n\ + \ FragColor = vec4(frag_col.x, frag_col.y, frag_col.z, 1.0f);\n\ + \}" + val graphLines: Real32.real vector = #[ (* x = ~0.95 *) diff --git a/imperative-shell/shell.sml b/imperative-shell/shell.sml index 2370f0e..0077ece 100644 --- a/imperative-shell/shell.sml +++ b/imperative-shell/shell.sml @@ -16,18 +16,19 @@ struct callbackListener mailbox end - fun loop (window, graphDrawObject) = + fun loop (window, graphDrawObject, buttonDrawObject) = if not (Glfw.windowShouldClose window) then let val _ = Gles3.clearColor (1.0, 1.0, 1.0, 1.0) val _ = Gles3.clear () val _ = AppDraw.drawGraphLines graphDrawObject + val _ = AppDraw.drawButton (buttonDrawObject, #[]) val _ = Glfw.pollEvents () val _ = Glfw.swapBuffers window in - loop (window, graphDrawObject) + loop (window, graphDrawObject, buttonDrawObject) end else Glfw.terminate () @@ -44,6 +45,7 @@ struct val _ = Gles3.loadGlad () val graphDrawObject = AppDraw.initGraphLines () + val buttonDrawObject = AppDraw.initButton () val inputMailbox = Mailbox.mailbox () (* Set callback sender *) @@ -63,7 +65,7 @@ struct (* Set callback listener *) val _ = CML.spawn (fn () => callbackListener inputMailbox) in - loop (window, graphDrawObject) + loop (window, graphDrawObject, buttonDrawObject) end end diff --git a/test.sml b/test.sml new file mode 100644 index 0000000..e69de29