OCaml の OpenGL用のライブラリ gles3 を利用して、GNUstep の NSOpenGLView に triangle を描画してみました。shader を使って描画します。
gles3 https://github.com/craff/gles3
[実行結果]

プロジェクト構成
/bin
/Resources
MainMenu.gorm
Info-gnustep.plist
dune
app_delegate.ml
main.ml
main_window.ml
dune-project
(プロジェクト名).opam
dune
(executable
(public_name gnustepAppTemplate2)
(name main)
(flags -ccopt -L/usr/local/GNUstep/System/Library/Libraries -cclib -lgnustep-base -cclib -lgnustep-gui)
(libraries
gles3
camlkitGS.Foundation
camlkitGS.AppKit
camlkitGS.camlkit))
(subdir GSApp.app
(rule
(deps ../main.exe)
(targets GSApp)
(action (copy ../main.exe GSApp))))
(subdir GSApp.app/Resources
(rule
(deps ../../Resources/Info-gnustep.plist)
(targets Info-gnustep.plist)
(action (progn
(copy ../../Resources/Info-gnustep.plist Info-gnustep.plist))))
)
(subdir GSApp.app/Resources/MainMenu.gorm
(rule
(deps ../../../Resources/MainMenu.gorm/objects.gorm ../../../Resources/MainMenu.gorm/data.classes ../../../Resources/MainMenu.gorm/data.info)
(targets objects.gorm data.classes data.info)
(action (progn
(copy ../../../Resources/MainMenu.gorm/objects.gorm objects.gorm)
(copy ../../../Resources/MainMenu.gorm/data.classes data.classes)
(copy ../../../Resources/MainMenu.gorm/data.info data.info))))
)
main.ml
open Foundation
open AppKit
open Camlkit
open Runtime
module Delegate = Appkit_AppDelegate.Create (App_delegate)
let main () =
let _ = new_object "NSAutoreleasePool"
and app = NSApplication.self |> NSApplicationClass.sharedApplication
and argc = Array.length Sys.argv
and argv =
Sys.argv
|> Array.to_list
|> Objc.(CArray.of_list string)
|> Objc.CArray.start
in
app |> NSApplication.setDelegate (_new_ Delegate._class_);
app |> NSApplication.activateIgnoringOtherApps true;
_NSApplicationMain argc argv |> exit
let () = main ()
app_delegate.ml
open Foundation open Runtime open AppKit let app_name = "gnustep-app" let class_name = "MyAppDelegate" let on_before_start _ = () let on_started notification = let app = NSNotification.object_ notification in let win = Main_window.create app in win |> NSWindow.setTitle (new_string app_name); ;; let on_before_terminate _ = () let terminate_on_windows_closed _ = true
main_window.ml
(* NSOpenGLView Triangle *)
open Foundation
open AppKit
open Runtime
open Egl
open Gles3
open Gles3.Type
open Shaders
open Buffers
let w = 400. and h = 400.
let gwidth = ref 400 and gheight = ref 350
let make_glView ~frame =
let glView =
_new_ NSOpenGLView.self in
glView |> NSView.setFrame frame;
glView
let light_shader =
("light_shader",
[{ name = "vertex_main";
ty = gl_vertex_shader;
src = "
in vec3 in_position;
void main()
{
gl_Position = vec4(in_position, 1.0);
}"};
{ name = "fragment_main";
ty = gl_fragment_shader;
src = "
out vec4 FragColor;
void main()
{
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}"};
])
let vertices : Gles3.float_bigarray = Buffers.to_float_bigarray
[| -0.5;-0.5;0.0; 0.0; 0.5;0.0; 0.5;-0.5;0.0; |]
let create app =
let win =
alloc NSWindow.self
|> NSWindow.initWithContentRect
(CGRect.make ~x: 0. ~y: 0. ~width: w ~height: h)
~styleMask: Bitmask.(
_NSWindowStyleMaskTitled +
_NSWindowStyleMaskClosable +
_NSWindowStyleMaskResizable)
~backing: _NSBackingStoreBuffered
~defer: false
and glView =
make_glView
~frame: (CGRect.make ~x: 0. ~y: 50. ~width: w ~height: (h -. 50.))
in
win
|> NSWindow.cascadeTopLeftFromPoint (CGPoint.init ~x: 200. ~y: 800.)
|> ignore;
win |> NSWindow.makeKeyAndOrderFront nil;
win |> NSWindow.contentView |> NSView.addSubview glView;
let glcontext = glView |> NSOpenGLView.openGLContext
in
glcontext|> NSOpenGLContext.makeCurrentContext;
clear_color { r = 0.7; g = 0.7; b = 0.7; a = 1.0 };
clear [ gl_color_buffer];
let prg : unit program = compile light_shader in
let prg = Shaders.float_cst_attr prg "in_position" vertices in
Shaders.draw_arrays prg gl_triangles 3;
glcontext |> NSOpenGLContext.flushBuffer;
win
;;Resources については、以前の記事参照。