-
Notifications
You must be signed in to change notification settings - Fork 65
Home
MLX42 is a performant, easy to use, cross-platform windowing library to create graphical applications without having to work directly with the native Windowing Framework of the given operating system.
Additionally it provides primitive tools for drawing onto the window such as displaying images from disk or creating a drawing surface to draw pixels on.
MLX42 is the proposed successor to the MiniLibX library which was written by Olivier Crouzet, almost 20 years ago back in Epitech. Most students agree that the library is written in a, well, subpar state and isn't the most optimal in terms of usability and documentation.
While it is "stable" and does compile there are many pitfalls with the library including the lack of good documentation, weird function prototypes and/or slow performance, e.g: putpixel. Additionally it is pretty much no longer truly being maintained nor is it open-source with the exception of the Linux version. Which I consider to not be the solution as its not using the native UI Framework and is just a different iteration of MiniLibX same goes for the Swift version. They aren't the solution to the problem, just different flavors of the same thing.
Most of my 42 peers simply stated that "it is what it is" once I discovered this library. However, personally, I refused to let this cycle continue. So I made it my goal that during one of many Lockdowns to start exploring OpenGL in order to finally fix the mistakes. I wrote it in OpenGL because using Vulkan is a bit overkill as well as being a lot more complex and not as approachable to students.
In my eyes, the 42 Network deserves high quality tools to teach people properly.
A list of improvements include:
- It is easy and straight-forward to install & compile.
- It is cross-platform (Linux, Windows & MacOS)
- Error handling, no more straight up segfaults.
- Clear and understandable English written documentation.
- No Leaks, compiles with
-fsanitize=address
effortlessly. - No abstracted data types, only things relevant to OpenGL are abstracted.
- Open-source, find a bug? Send a PR to this repo!
- Useful extra features such as:
- Apply a custom application icon for your program.
- Apply a custom cursor, finally you can have a cool fire sword cursor!
- Universal enums for keycodes, mouse buttons, no more searching what keycode is for what OS.
- Easy input handling, no more 3 different types of inputs (Events, masks, hooks). Just a single hook or if statement.
- Custom XPM image format (XPM42).
- An actual efficient
mlx_put_pixel
function. - Ability to retrieve the delta time, now you can make fancy interpolations.
- Ability to retrieve monitor width and height as well getting and setting window position.
- Ability to focus the window.
- Ability to resize the window.
Currently supported operating systems:
Operating system | Version |
---|---|
Windows NT |
Windows 7 - Windows 11 |
MacOS |
Mojave - Monterey (Including Apple Silicon) |
Linux |
Anything running X11 / Wayland |
The very first step for initialization is to execute the mlx_init function. It is responsible for setting up the GLFW windowing library which creates a connection between your software and the display. It also loads the OpenGL function pointers, compiling the shaders and more.
It returns a mlx_t* which is a structure containing the current window instance. With this instance you can manipulate, hook onto and control what happens inside your window instance. For example you would use it to send graphical instructions such as creating an image, which is used to display pixel data. You can also detect key interactions such as checking if the W, A, S or D key is currently being pressed.
Function | Description |
---|---|
mlx_init() |
Initialize and run a new window instance. |
mlx_loop() |
Keep the window open as long as a shutdown is not requested. |
mlx_terminate() |
Destroy and clean up all images and mlx resources. |
If mlx_init() fails to set up the connection to the graphical system, it will return NULL, otherwise a non-null pointer is returned as a handle for the window.
In order to use the functions in MLX, you'll need to link it with your application.
To do this, simply add the following arguments at the linking stage:
Operating System | Flags |
---|---|
Windows NT |
-lglfw3 -lopengl32 -lgdi32 |
MacOS |
-lglfw(3) -framework Cocoa -framework OpenGL -framework IOKit |
Linux |
-ldl -lglfw(3) -pthread -lm |
NOTE: For some UNIX systems the flag for glfw might be with or without a 3 at the end.
MLX was designed with ease of debugging in mind, therefore if the project is built with cmake -DDEBUG=1 it will keep in the assertion macros and notify you of any bad input given to functions. Additionally it comes with its own runtime error checking via mlx_errno and mlx_strerror to properly identify what went wrong during the runtime of the library.
Keep in mind that while technically MLX42 does support multiple window instances it currently has no functional support for it. That is, no proper way of handling multiple windows.
Q: "It'S NoT In ThE SuBjeCt!"
A: So what? Subjects can change and so if something is not working correctly it should be replaced. Sure you can argue this point but you can also be the reason that it CAN be in the subject instead. Have an open mind :)
Q: "Ok, so, can I use it ?"
A: Officially, no. However, ask your head of studies first about using it, see what they think. Some students might be evangelical enthusiasts about what is stated in the subject and are technically in every right to fail you as long as this library is not endorsed, if you were to ask me (W2) then yes why not?
Q: "Is it faster?"
A: From my personal projects there was a considerable peformance gain, especially when compiled with -Ofast
. Projects such as FDF could rotate their maps mindblowingly smooth and even larger maps with a width and height of 1000+ points moved/rotated relatively smooth, so in short, yes.
Q: "Can I just drag and drop it into my old project and just not do anything?"
A: No. That's not how libraries work. Sure they target and do sort of the same thing but the functions each library provides are too different, even a little bit in terms of behavior. And no there is no easy way to convert from the "old" to the "new" it will be somewhat tedious work.
Q: "We should be able to deal with the fact that MiniLibX is not perfect, it is by design and makes us better programmers."
A: Struggle does bring out the best in most people but it is also not ideal in this case. I think so at least, that it's really expected that libraries that are publicly available should be usable, stable, easy to use and well documented. Nobody uses a library because it is annoying to work with and afterwards think to themselves they have learned something after they are done struggling. The only thing people learn from this is how to navigate around the shortcomings instead.
Q: "Why not use some other library? Why this one and not any other library."
A: It is your choice what to use! I wrote this in my free time in an attempt to introduce some good change and to improve the learning experience at 42. If you don't like my library at least let me know what it is so I can improve on it.
Q: "Do you hate MiniLibX? Is this some personal vendetta, do you work for the CIA ?"
A: No, I just want to improve 42, that's it.