raylib

The open source C library raylib provides an API for 2-D and 3-D graphics programming, mainly for computer and video games, on all major platforms without external dependencies. Interface bindings are available for more than 60 programming languages, including Fortran. The library features:

Raylib can be combined with extra libraries for additional functionality, like raygui, a simple immediate-mode GUI library.

Voyager model in Fortran
Fig. 1: NASA model of the Voyager spacecraft rendered with Fortran and raylib

Installation

The library has to be compiled from source if no binary package is available for the targeted operating system. On FreeBSD, unpack the source archive, create a new Makefile with CMake, then build, and install raylib system-wide:

$ tar xfvz raylib-5.5.tar.gz
$ cd raylib-5.5/
$ mkdir build && cd build/
$ cmake ..
$ make PLATFORM=PLATFORM_DESKTOP
$ make install

Alternatively, you may want to use the current master branch of the source code repository instead. Afterwards, download or clone the Fortran 2018 interface bindings fortran-raylib, and execute the Makefile:

$ git clone https://github.com/interkosmos/fortran-raylib
$ cd fortran-raylib/
$ make

The fortran-raylib library may be added as a dependency to the build manifest of the Fortran Package Manager, if preferred:

[dependencies]
fortran-raylib = { git = "https://github.com/interkosmos/fortran-raylib.git" }

Either link against the static raylib library libraylib.a, or the shared one -lraylib, additionally to the interface bindings libfortran-raylib.a. See the bindings documentation for more information.

Example

The example program shown in this section will render a 3-D model of the Voyager consisting of 17,602 polygons that was created by NASA/JPL-Caltech and released as public domain. The model voyager.glb (2.1 MiB) in glTF format has been converted from the original Blender file.

The program rotates the model each frame in Z (fig. 1). Look around the 3-D world by using the mouse, move by pressing the keys W, A, S, D, and rotate with Q and E.

! voyager.f90
program main
    use, intrinsic :: iso_c_binding
    use :: raylib
    implicit none (type, external)

    integer, parameter :: SCREEN_WIDTH  = 800
    integer, parameter :: SCREEN_HEIGHT = 450

    real                 :: angle
    type(camera3d_type)  :: camera
    type(model_type)     :: model
    type(vector3_type)   :: position, rotation, scale

    ! Enable V-Sync and anti-aliasing, initialise window, and disable mouse pointer.
    call set_config_flags(ior(FLAG_VSYNC_HINT, FLAG_MSAA_4X_HINT))
    call init_window(SCREEN_WIDTH, SCREEN_HEIGHT, 'Voyager' // c_null_char)
    call disable_cursor()

    ! Define camera to look into our 3-D world.
    camera%position   = vector3_type(10.0, 10.0, 10.0) ! Camera position vector.
    camera%target     = vector3_type(0.0, 0.0, 0.0)    ! Camera target vector.
    camera%up         = vector3_type(0.0, 1.0, 0.0)    ! Camera up vector.
    camera%fov_y      = 45.0                           ! Camera field of view [deg].
    camera%projection = CAMERA_PERSPECTIVE             ! Camera projection.

    ! Load model from file.
    model = load_model('voyager.obj' // c_null_char)

    ! Set model parameters.
    angle    = 0.0                         ! Rotation angle [deg].
    rotation = vector3_type(0.0, 0.0, 1.0) ! Rotation vector.
    scale    = vector3_type(2.0, 2.0, 2.0) ! Scale factor.

    ! The rendering loop.
    do while (.not. window_should_close())
        call update_camera(camera, CAMERA_FIRST_PERSON)

        angle = modulo(angle + 0.1, 360.0)

        call begin_drawing()
            call clear_background(RAYWHITE)

            call begin_mode3d(camera)
                call draw_model_ex(model, position, rotation, angle, scale, WHITE)
            call end_mode3d()

            call draw_fps(10, 10)
        call end_drawing()
    end do

    ! Clean-up and close window.
    call unload_model(model)
    call close_window()
end program main

All character strings passed to raylib have to be properly null-terminated with c_null_char at the end. Otherwise, weird segmentation faults may occur.

On FreeBSD, build and link the executable with:

$ gfortran13 -o voyager voyager.f90 libfortran-raylib.a libraylib.a -lGL -lpthread -lm

To link against the shared raylib library, replace libraylib.a with -lraylib. Make sure that the model file voyager.glb is in the same directory as the binary. Then, run:

$ ./voyager

Fortran Libraries

Fortran Games

References