done scaffolding cml and adding resize functionality

This commit is contained in:
2024-10-06 10:23:07 +01:00
parent b95fc48252
commit 68a1787958
9 changed files with 92 additions and 13 deletions

View File

@@ -2,4 +2,7 @@ structure AppType =
struct struct
type app_type = type app_type =
{buffer: LineGap.t, windowWidth: int, windowHeight: int} {buffer: LineGap.t, windowWidth: int, windowHeight: int}
fun init (buffer, windowWidth, windowHeight): app_type =
{buffer = buffer, windowWidth = windowWidth, windowHeight = windowHeight}
end end

View File

@@ -1,4 +1,5 @@
#include "export.h" #include "export.h"
#include "glad.h"
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -6,3 +7,12 @@ int PRESS = GLFW_PRESS;
int REPEAT = GLFW_REPEAT; int REPEAT = GLFW_REPEAT;
int RELEASE = GLFW_RELEASE; int RELEASE = GLFW_RELEASE;
void framebufferSizeCallback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
mltonFramebufferSizeCallback(width, height);
}
void setFramebufferSizeCallback(GLFWwindow* window) {
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
}

View File

@@ -17,4 +17,6 @@ struct
val exportFramebufferSizeCallback = val exportFramebufferSizeCallback =
_export "mltonFramebufferSizeCallback" public : (int * int -> unit) -> unit; _export "mltonFramebufferSizeCallback" public : (int * int -> unit) -> unit;
val setFramebufferSizeCallback =
_import "setFramebufferSizeCallback" public : window -> unit;
end end

View File

@@ -1,4 +1,10 @@
structure DrawMsg = signature DRAW_MSG =
sig
datatype t =
REDRAW_TEXT of Real32.real vector
end
structure DrawMsg :> DRAW_MSG =
struct struct
datatype t = datatype t =
REDRAW_TEXT of Real32.real vector REDRAW_TEXT of Real32.real vector

View File

@@ -1,4 +1,10 @@
structure InputMsg = signature INPUT_MSG =
sig
datatype t =
RESIZE_EVENT of int * int
end
structure InputMsg :> INPUT_MSG =
struct struct
datatype t = datatype t =
RESIZE_EVENT of int * int RESIZE_EVENT of int * int

View File

@@ -1,4 +1,10 @@
structure MailboxType = signature MAILBOX_TYPE =
sig
datatype t =
DRAW of DrawMsg.t
end
structure MailboxType :> MAILBOX_TYPE =
struct struct
datatype t = datatype t =
DRAW of DrawMsg.t DRAW of DrawMsg.t

View File

@@ -1,5 +1,7 @@
structure GlDraw = structure GlDraw =
struct struct
open CML
open DrawMsg
(* The name doesn't make it clear, but this structure (* The name doesn't make it clear, but this structure
* couples GLFW and OpenGL. * couples GLFW and OpenGL.
* I'm not sure if I will use native windowing systems * I'm not sure if I will use native windowing systems
@@ -10,6 +12,7 @@ struct
{ textVertexBuffer: Word32.word { textVertexBuffer: Word32.word
, textProgram: Word32.word , textProgram: Word32.word
, textDrawLength: int , textDrawLength: int
, drawMailbox: DrawMsg.t Mailbox.mbox
, window: MLton.Pointer.t , window: MLton.Pointer.t
} }
@@ -32,7 +35,7 @@ struct
program program
end end
fun create window = fun create (drawMailbox, window) =
let let
(* create vertex buffer, program, etc. for text. *) (* create vertex buffer, program, etc. for text. *)
val textVertexBuffer = Gles3.createBuffer () val textVertexBuffer = Gles3.createBuffer ()
@@ -51,19 +54,24 @@ struct
{ textVertexBuffer = textVertexBuffer { textVertexBuffer = textVertexBuffer
, textProgram = textProgram , textProgram = textProgram
, textDrawLength = 0 , textDrawLength = 0
, drawMailbox = drawMailbox
, window = window , window = window
} }
end end
fun uploadText fun uploadText (shellState: t, vec) =
({textVertexBuffer, textProgram, window, textDrawLength = _}: t, vec) =
let let
val
{textVertexBuffer, textProgram, window, drawMailbox, textDrawLength = _} =
shellState
val _ = Gles3.bindBuffer textVertexBuffer val _ = Gles3.bindBuffer textVertexBuffer
val _ = Gles3.bufferData (vec, Vector.length vec, Gles3.STATIC_DRAW) val _ = Gles3.bufferData (vec, Vector.length vec, Gles3.STATIC_DRAW)
val newTextDrawLength = Vector.length vec div 5 val newTextDrawLength = Vector.length vec div 5
in in
{ textVertexBuffer = textVertexBuffer { textVertexBuffer = textVertexBuffer
, textProgram = textProgram , textProgram = textProgram
, drawMailbox = drawMailbox
, window = window , window = window
, textDrawLength = newTextDrawLength , textDrawLength = newTextDrawLength
} }
@@ -93,10 +101,30 @@ struct
in () in ()
end end
fun consumeDrawEvent (shellState, msg) =
let
val
{textVertexBuffer, textProgram, window, drawMailbox, textDrawLength = _} =
shellState
in
case msg of REDRAW_TEXT textVec => uploadText (shellState, textVec)
end
fun consumeDrawEvents (shellState as {drawMailbox, ...}: t) =
case Mailbox.recvPoll drawMailbox of
NONE => shellState
| SOME msg =>
let val shellState = consumeDrawEvent (shellState, msg)
in consumeDrawEvents shellState
end
fun helpLoop (shellState as {window, ...}: t) = fun helpLoop (shellState as {window, ...}: t) =
case Glfw.windowShouldClose window of case Glfw.windowShouldClose window of
false => false =>
let let
val shellState = consumeDrawEvents shellState
val _ = Gles3.clearColor (1.0, 1.0, 1.0, 1.0) val _ = Gles3.clearColor (1.0, 1.0, 1.0, 1.0)
val _ = Gles3.clear () val _ = Gles3.clear ()
@@ -109,8 +137,8 @@ struct
end end
| true => Glfw.terminate () | true => Glfw.terminate ()
fun loop window = fun loop (drawMailbox, window) =
let val shellState = create window let val shellState = create (drawMailbox, window)
in helpLoop shellState in helpLoop shellState
end end
end end

View File

@@ -1,6 +1,19 @@
structure Shell = structure Shell =
struct struct
open CML open CML
open InputMsg
fun frameBufferSizeCallback inputMailbox (width, height) =
Mailbox.send (inputMailbox, RESIZE_EVENT (width, height))
fun registerCallbacks (inputMailbox, window) =
let
val resizeCallback = frameBufferSizeCallback inputMailbox
val () = Input.exportFramebufferSizeCallback resizeCallback
val () = Input.setFramebufferSizeCallback window
in
()
end
fun ioToLineGap (io, acc) = fun ioToLineGap (io, acc) =
case TextIO.inputLine io of case TextIO.inputLine io of
@@ -18,16 +31,21 @@ struct
val _ = Glfw.makeContextCurrent window val _ = Glfw.makeContextCurrent window
val _ = Gles3.loadGlad () val _ = Gles3.loadGlad ()
(* upload text vector *) (* load file intol gap buffer and create initial app *)
val io = TextIO.openIn "fcore/text-builder.sml" val io = TextIO.openIn "fcore/text-builder.sml"
val lineGap = ioToLineGap (io, LineGap.empty) val lineGap = ioToLineGap (io, LineGap.empty)
val _ = TextIO.closeIn io val _ = TextIO.closeIn io
val app = AppType.init (lineGap, 1920, 1080)
val (textVec, _) = TextBuilder.build (0, lineGap, 1920, 1080) (* create mailboxes for CML communication *)
val shellState = GlDraw.create window val inputMailbox = Mailbox.mailbox ()
val shellState = GlDraw.uploadText (shellState, textVec) val drawMailbox = Mailbox.mailbox ()
val _ = GlDraw.helpLoop shellState val () = registerCallbacks (inputMailbox, window)
val _ = CML.spawn (fn () => GlDraw.loop (drawMailbox, window))
val _ = CML.spawn (fn () =>
UpdateThread.loop (app, inputMailbox, drawMailbox))
in in
() ()
end end

BIN
shf

Binary file not shown.