Greetings everyone!
(Caution - lengthy context ahead!)
A little while ago I started a small project, which aims to be a program that would create animation from a text script written in a specially designed language. For the lack of a better comparison, imagine a virtual machine which has a set of instructions that manipulate objects such as 2D sprites, backgrounds and 3D models, and you as the animator write a program with these instructions describing exactly what you want to see, such as movements, rotations, transformations, etc. The project has been created in Python since the very beginning, but I’ve always understood that a project like that would eventually become computationally intensive and an interpreted language would not be able to sustain it. After much consideration, I’ve chosen Fortran, since its syntax felt most familiar and comfortable to me when compared to C/C++ and alike. I should mention that all of the code is written from scratch, meaning that almost no libraries are used - the only ones I used initially were math, used for trigonometric functions that are utilised in the engine (no matrices are involved in 3D), and pygame, which was used exclusively to provide a video output. Even the codec used to record and playback the resulting animation is original. The codec was the module that I decided to transition first, since the original implementation was lagging when the window was being recorded and I couldn’t optimize the decoder for any sort of considerable speed gain. While researching Fortran, I found that there is a library that might just perfectly suit my needs - SDL2, but that’s where problems began. I wasn’t been able to find a comprehensive guide on how to actually attach and use it, which is further made difficult by my absolute lack of experience with compiled languages and their inherent oddities. Therefore, I would like to ask, how do I install and attach SDL2 to my project? I’m using CodeBlocks under Windows 11, and the only thing that’s needed from SDL2 is opening a window and drawing an image on it from a prepared array which acts as a frame buffer (plus playing a sound at a selected rate from a prepared array of raw sample data). Using any other OS is not an option, installing WSL is possible but not preferred and would only be desirable if no other options exist.
Hello @Jozeff, welcome to Discourse!
You can find a description about how to use SDL2 from Fortran, courtesy of @interkosmos, here: SDL | Programming in Modern Fortran.
Concerning installation on Windows, have you followed the steps at the SDL Wiki (SDL2/Installation - SDL Wiki)? It looks like the first step is to download the binary package from GitHub: Releases · libsdl-org/SDL · GitHub. Next step would be to configure the library path in your IDE.
Since your profile suggests you have an interest in retro tech, you could also give the SDL77 interface a try. Here’s a sample program I got running in about 1 hr (I’m on a Mac):
sdl77_pixels
program sdl77_pixels
implicit none
! SDL77 interface
external :: galloc, gblit, gcirc, gclose, gcolor, gcolk, &
gcppal, gcppix, gcreat, gcur, gdelay, gevent, &
gfill, gfillr, gflush, ggrab, ghline, glayer, &
gline, gload, glock, gmbut, gmouse, gopen, gpal, &
gpixel, gsetp, gsshot, gulock, gvideo, gvline, &
gwarp, gkey, gticks, gtime
! External functions
integer :: gkey
integer(8) :: gticks, gtime
integer, parameter :: EVENT_QUIT = 12
integer, parameter :: kreturn = 13
integer, parameter :: kspace = 32
integer, parameter :: kesc = 27
integer, parameter :: kup = 273
integer, parameter :: kdown = 274
integer, parameter :: kright = 275
integer, parameter :: kleft = 276
integer, parameter :: pw = 320, ph = 160, blk = 4
integer, parameter :: wwidth = blk*pw, wheight = blk*ph
real :: pix(ph,pw)
integer :: istat, ievent
! Open window and hide mouse cursor
call gopen(wwidth,wheight,"pixel noise"//achar(0),istat)
if (istat /= 0) stop "Error: failed to open SDL window"
call gcur(0)
! Set background color and fill screen
call gcolor(0,0,0)
call gfill()
main: do
! Poll for events
event: do
call gevent(ievent,istat)
if (ievent == EVENT_QUIT) exit main
if (istat == 0) exit event
end do event
! Respond to key presses
if (gkey(kup) == 1) then
call randomize
else if (gkey(kdown) == 1) then
call clear
else if (gkey(kleft) == 1) then
call left
else if (gkey(kright) == 1) then
call right
else if (gkey(kspace) == 1) then
call automaton
else if (gkey(kesc) == 1) then
exit main
end if
! Draw pixel-blocks
call render
call gflush
end do main
call gclose()
contains
subroutine render
integer :: i, j
do i = 1,pw
do j = 1,ph
if (pix(j,i) > 0.5) then
call gcolor(255,255,255)
else
call gcolor(0,0,0)
end if
call gfillr(blk*i-blk,blk*j-blk,blk,blk)
end do
end do
end subroutine
subroutine randomize
call random_number(pix)
end subroutine
subroutine clear
pix = 0.0
end subroutine
subroutine left
pix = cshift(pix,blk,dim=2)
end subroutine
subroutine right
pix = cshift(pix,-blk,dim=2)
end subroutine
subroutine automaton
logical, save :: switch = .false.
integer :: i, j, im, ip, jl, jh, js
logical :: p, q, r, c
if (switch) then
jl = 2
jh = ph
js = 1
else
jl = ph-1
jh = 1
js = -1
end if
do j = jl, jh, js
do i = 1, pw
ip = modulo(i+1,pw) + 1
im = modulo(i-1,pw) + 1
p = pix(j-js,im) > 0.5
q = pix(j-js,i) > 0.5
r = pix(j-js,ip) > 0.5
c = r .neqv. (q .or. p)
if (c) then
pix(j,i) = 1.0
else
pix(j,i) = 0.0
end if
end do
end do
switch = .not. switch
end subroutine
end program
The controls are:
- up - randomize pixels
- left/right - pane
- down - reset
- space - cellular automation (Rule 110)
- esc - close program
Hope that helps.
Ivan
I did some miniproject some time ago, feel free to use it as an example: Fortran Game of life
Game of Life was going to be my next idea for a (nightly) Fortran SDL project. I’m glad you’ve done it already.
I also created a custom SDL2 backend in C with Fortran bindings for the Fortran CHIP8 virtual machine. SDL2 was easier to use than Xlib. Initially I tried using EGGX/ProCall but it lacked the functionality to distinguish key releases from key presses.