MLX42 是一个高性能、易于使用、跨平台、最小窗口图形库,用于创建图形应用程序,而无需直接使用给定操作系统的本机窗口框架。
它提供了原始工具来将纹理绘制到窗口上,并在运行时在它们显示在窗口上时对其进行修改。
重要的
有时,看起来似乎已经很长时间没有更新了。这是预期的,项目/lib 被认为已完成并且需要最少的更新。仍然保证错误修复,并且该项目仍在积极维护中。
MLX42 具有大量功能,使使用它实际上成为一种乐趣,而不是一件苦差事。
在你祖母的 WindowsXP、你叔叔的 Debian 或时髦人士的 MacOS 上运行它!无论什么平台,如果 MLX42 可以在其上构建,它将在其本机窗口系统上运行。
这使您无论在哪台机器上都可以处理您的项目。
MLX42 注重良好的文档,每个功能、用法甚至一些内部工作都有文档记录!不再需要猜测和搜索某些东西如何运作或应该如何运作。
它基于 OpenGL 构建,并使用批处理渲染来加速渲染过程(与其他库相比)。
该项目由 Codam 以及 42 Network 的学生积极维护。这使学生有直接的机会更多地了解库本身并修复任何潜在的错误,而不是仅仅接受它们。
MLX42 引入了与 Emscripten 的兼容性,允许 MLX42 通过 WebAssembly 在 Web 浏览器中运行。这一修改之所以成为可能,要归功于@PepeLevi,感谢他的分叉和贡献。
总体而言,该项目的所有系统的构建如下。只要CMake能够理解就可以了。
如果您的系统没有安装 glfw,cmake 会检测到它并为您下载。然后您可以在glfw的_deps
目录中运行sudo make install
。如果您使用的是 42 位计算机(MacOS、Linux),请让您最喜欢的系统管理员来安装它。对于 CMake 或系统可能需要的任何其他依赖项也是如此。
但是,如果您不能执行任何操作,CMake 仍然能够获取 GLFW 并构建它。然后,您可以从_deps
文件夹静态链接它。
笔记
对于 Codam,GLFW 已安装在 Mac 上。
笔记
在链接阶段,链接 GLFW 的标志可以是:-lglfw3 或 -lglfw,具体取决于您的系统。
使用库编译您的程序:
利润!
要完全构建该库并将其安装到您的系统中,请运行以下命令:
cmake -B build && cmake --build build --parallel --config (Debug | Release | RelWithDebInfo | MinSizeRel) --target install
默认情况下,Windows 会将安装的库放入: C:Program Files (x86)mlx42
,对于 MacOS / Linux,它将分别放入/usr/local/lib
和/usr/local/include
中。
MLX42 附带了一些单元测试来确保库的完整性,要构建它们,请运行以下命令:
cmake -DBUILD_TESTS=ON -B build && cmake --build build --parallel
然后只需运行它们:
ctest --output-on-failure --test-dir build
git clone https://github.com/codam-coding-college/MLX42.git
cd MLX42
cmake -B build # build here refers to the outputfolder.
cmake --build build -j4 # or do make -C build -j4
输出库文件名为libmlx42.a
,位于您指定的build
文件夹中。
您可以将构建选项传递给 cmake,例如: cmake -DDEBUG=1 -DGLFW_FETCH=0...
。例如,这些可以让您在调试模式下构建它或在构建时改变任何类型的行为。
您可以在此处的文档中找到示例 makefile。
如果您的系统既没有 GLFW 也没有 CMake,强烈建议您使用 brew 来安装那些缺少的依赖项。
对于 42 个校区,您可以使用:42Homebrew
否则使用自制程序:
brew install glfw
brew install cmake
如果您使用 Apple Silicon(M1 芯片或更高版本),请注意 Homebrew 安装路径是不同的。您可能想要更新 shell 配置文件。对于 Zsh 用户(较新 macOS 版本上的默认 shell):
nano ~ /.zshrc
export LIBRARY_PATH=/opt/homebrew/lib
重新启动 shell 会话或重新启动终端以使更改生效。
对于 MacOS,您需要使用以下标志来使用库编译您的程序,以便将程序与正确的框架链接:
-framework Cocoa -framework OpenGL -framework IOKit
通常,如果您只是从源代码安装/构建glfw
或已经安装了它,则编译应该是:
gcc main.c ... libmlx42.a -Iinclude -lglfw
# Homebrew
gcc main.c ... libmlx42.a -Iinclude -lglfw -L " /opt/homebrew/Cellar/glfw/3.3.8/lib/ "
# 42Homebrew
gcc main.c ... libmlx42.a -Iinclude -lglfw -L " /Users/ $( USER ) /.brew/opt/glfw/lib/ "
当在 MacOS 中运行你的程序时,它可能会抱怨,因为使用 Mac,你必须以不同的方式思考。如果出现任何安全警告或 MacOS 告诉您无法验证作者/开发者,请转至Settings > Security & Privacy
。
底部会弹出一个窗口,告诉您有一个应用程序尝试运行,单击该选项让它运行。
对于 Debian,例如(Ubuntu、Mint、Pop OS...):
sudo apt update
sudo apt install build-essential libx11-dev libglfw3-dev libglfw3 xorg-dev
对于 Arch-linux(Manjaro、Endeavor、Garuda):
sudo pacman -S glfw-x11
或者(如果您使用 sway/wlroots 合成器或其他 Wayland 合成器)
sudo pacman -S glfw-wayland
下载并构建 MLX42
使用库编译您的程序:
gcc main.c ... libmlx42.a -Iinclude -ldl -lglfw -pthread -lm
重要的
在开始执行所有这些步骤之前,请阅读此内容
.zshrc
或.bashrc
中设置这些变量: export DISPLAY= $( ip route list default | awk ' {print $3} ' ) :0
export LIBGL_ALWAYS_INDIRECT=0
(如果 DISPLAY 导出命令失败,请参阅此 StackOverflow 帖子以获取替代方案)
下载并安装具有扩展配置的 XServer 应用程序(XMing 不合格) VcXsrv 可以工作:https://sourceforge.net/projects/vcxsrv/
打开 Windows Defender 防火墙,然后按照以下步骤操作:
Native opengl
选项Disable access control
重要的
请注意,为此需要 Visual Studio (2022)。在 Windows 上进行开发可能会有些令人沮丧。
我们强烈建议您使用 WSL2 来尽可能轻松地完成此操作。但是,如果您坚持本地构建 Windows,那么您所需要的依赖项就是:
正确安装所有依赖项后, CMake
将生成 Visual Studio 项目文件。只需构建它,一旦您拥有.lib
文件,请将它们移动到您的实际项目并像安装任何其他库一样安装它们。
以防万一,这里有一个视频向您展示了如何做到这一点。方便地,该视频还介绍了如何链接glfw
。
当然,您需要确保您编写的代码是可移植的。 Unix
上存在的东西不一定存在于Win32
上。
// -----------------------------------------------------------------------------
// Codam Coding College, Amsterdam @ 2022-2023 by W2Wizard.
// See README in the root project for more information.
// -----------------------------------------------------------------------------
#include
#include
#include
#include
#define WIDTH 512
#define HEIGHT 512
static mlx_image_t * image ;
// -----------------------------------------------------------------------------
int32_t ft_pixel ( int32_t r , int32_t g , int32_t b , int32_t a )
{
return ( r << 24 | g << 16 | b << 8 | a );
}
void ft_randomize ( void * param )
{
( void ) param ;
for ( uint32_t i = 0 ; i < image -> width ; ++ i )
{
for ( uint32_t y = 0 ; y < image -> height ; ++ y )
{
uint32_t color = ft_pixel (
rand () % 0xFF , // R
rand () % 0xFF , // G
rand () % 0xFF , // B
rand () % 0xFF // A
);
mlx_put_pixel ( image , i , y , color );
}
}
}
void ft_hook ( void * param )
{
mlx_t * mlx = param ;
if ( mlx_is_key_down ( mlx , MLX_KEY_ESCAPE ))
mlx_close_window ( mlx );
if ( mlx_is_key_down ( mlx , MLX_KEY_UP ))
image -> instances [ 0 ]. y -= 5 ;
if ( mlx_is_key_down ( mlx , MLX_KEY_DOWN ))
image -> instances [ 0 ]. y += 5 ;
if ( mlx_is_key_down ( mlx , MLX_KEY_LEFT ))
image -> instances [ 0 ]. x -= 5 ;
if ( mlx_is_key_down ( mlx , MLX_KEY_RIGHT ))
image -> instances [ 0 ]. x += 5 ;
}
// -----------------------------------------------------------------------------
int32_t main ( void )
{
mlx_t * mlx ;
// Gotta error check this stuff
if (!( mlx = mlx_init ( WIDTH , HEIGHT , "MLX42" , true)))
{
puts ( mlx_strerror ( mlx_errno ));
return ( EXIT_FAILURE );
}
if (!( image = mlx_new_image ( mlx , 128 , 128 )))
{
mlx_close_window ( mlx );
puts ( mlx_strerror ( mlx_errno ));
return ( EXIT_FAILURE );
}
if ( mlx_image_to_window ( mlx , image , 0 , 0 ) == -1 )
{
mlx_close_window ( mlx );
puts ( mlx_strerror ( mlx_errno ));
return ( EXIT_FAILURE );
}
mlx_loop_hook ( mlx , ft_randomize , mlx );
mlx_loop_hook ( mlx , ft_hook , mlx );
mlx_loop ( mlx );
mlx_terminate ( mlx );
return ( EXIT_SUCCESS );
}