当前位置: 首页 > article >正文

Java使用FFM API调用SDL

首发于Enaium的个人博客


首先我们需要创建一个Gradle项目,之后设置项目的JDK版本,设置为22及以上版本。

plugins {
    kotlin("jvm") version "2.1.0"
}

group = "cn.enaium"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(kotlin("test"))
}

tasks.test {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(23)
}

接着我们在当前目录初始化git仓库,之后需要添加一个子模块。、

git init
git submodule add git@github.com:libsdl-org/SDL.git SDL

之后编写生成接口的脚本,在这之前你必须安装CMake和jextract到环境变量中。

$sdl_path = "SDL"
mkdir "$sdl_path/build"; cmake -DCMAKE_BUILD_TYPE=Release "$sdl_path" -B "$sdl_path/build"; cmake --build "$sdl_path/build" --config Release --parallel
jextract --include-dir "$sdl_path/include" --dump-includes "$sdl_path/build/includes.txt" "$sdl_path/include/SDL3/SDL.h"
jextract --include-dir "$sdl_path/include" --output src/main/java --target-package org.libsdl --library SDL3 --use-system-load-library "@$sdl_path/build/includes.txt" "$sdl_path/include/SDL3/SDL.h"

首先是使用CMake编译SDL,之后使用jextract生成Java接口,之后运行脚本,这样就会在src/main/java生成SDL3的接口。

接着我们回到build.gradle.kts,添加application插件,之后将编译好的路径添加到启动参数中。

plugins {
    application
}

application {
    mainClass = "MainKt"
    applicationDefaultJvmArgs = listOf("-Djava.library.path=SDL/build/Release", "--enable-native-access=ALL-UNNAMED")
}

之后就可以调用SDL的接口了。

import org.libsdl.*
import org.libsdl.SDL_h_1.*
import java.lang.foreign.Arena

/**
 * @author Enaium
 */
fun main() {
    Arena.ofConfined().use {
        val init = SDL_h_2.SDL_Init(SDL_INIT_VIDEO() and SDL_INIT_EVENTS())

        if (!init) {
            println("SDL_Init Error: ${SDL_h_3.SDL_GetError()}")
            return
        }

        val windowPtr = it.allocate(C_POINTER)
        val rendererPtr = it.allocate(C_POINTER)

        SDL_CreateWindowAndRenderer(it.allocateFrom("Hello World"), 640, 480, 0, windowPtr, rendererPtr)

        val window = windowPtr.get(C_POINTER, 0)
        val renderer = rendererPtr.get(C_POINTER, 0)

        val rect = SDL_FRect.allocate(it)
        SDL_FRect.x(rect, 100f)
        SDL_FRect.y(rect, 100f)
        SDL_FRect.w(rect, 440f)
        SDL_FRect.h(rect, 280f)


        val event = SDL_Event.allocate(it)
        var quit = false
        while (!quit) {
            while (SDL_PollEvent(event)) {
                when (SDL_Event.type(event)) {
                    SDL_EVENT_QUIT() -> {
                        quit = true
                    }

                    SDL_EVENT_KEY_DOWN() -> {
                        when (SDL_KeyboardEvent.key(SDL_Event.key(event))) {
                            SDLK_UP() -> {
                                SDL_FRect.y(rect, SDL_FRect.y(rect) - 5)
                            }

                            SDLK_DOWN() -> {
                                SDL_FRect.y(rect, SDL_FRect.y(rect) + 5)
                            }

                            SDLK_LEFT() -> {
                                SDL_FRect.x(rect, SDL_FRect.x(rect) - 5)
                            }

                            SDLK_RIGHT() -> {
                                SDL_FRect.x(rect, SDL_FRect.x(rect) + 5)
                            }
                        }
                    }
                }
            }

            SDL_h_2.SDL_SetRenderDrawColor(renderer, 33.toByte(), 33.toByte(), 33.toByte(), 255.toByte())
            SDL_h_2.SDL_RenderClear(renderer)

            SDL_h_2.SDL_SetRenderDrawColor(renderer, 0.toByte(), 0.toByte(), 255.toByte(), 255.toByte())

            SDL_h_2.SDL_RenderFillRect(renderer, rect)

            SDL_h_2.SDL_RenderPresent(renderer)
        }

        SDL_h_2.SDL_DestroyRenderer(renderer)
        SDL_h_3.SDL_DestroyWindow(window)
    }
}

首先这里创建了一个窗口和渲染器,还渲染了一个矩形。之后做了事件处理,关闭的时候跳出循环,之后销毁窗口和渲染器。按下键盘上下左右键可以移动矩形。

之后调用./gradlew run就可以运行程序了。


http://www.kler.cn/a/519570.html

相关文章:

  • 工厂模式 - 工厂方法模式、抽象工厂模式
  • 第五节 MATLAB命令
  • 人格分裂(交互问答)-我想懂Elasticsearch
  • AWScurl笔记
  • ansible自动化运维实战--软件包管理模块、服务模块、文件模块和收集模块setup(4)
  • An OpenGL Toolbox
  • Web3与传统互联网的对比:去中心化的未来路径
  • 随机矩阵投影长度保持引理及其证明
  • 渗透测试--攻击常见的Web应用
  • Windows系统Tai时长统计工具的使用体验
  • 2D 超声心动图视频到 3D 心脏形状重建的临床应用| 文献速递-医学影像人工智能进展
  • jeecg后端登录接口
  • 提示词工程
  • 浅谈Unity中Canvas的三种渲染模式
  • python介绍ransac算法拟合圆
  • rust学习-所有权
  • MongoDB使用详解
  • 【多视图学习】Self-Weighted Contrastive Fusion for Deep Multi-View Clustering
  • 无人机如何自主侦察?UEAVAD:基于视觉的无人机主动目标探测与导航数据集
  • 记录备战第十六届蓝桥杯的过程
  • JVM堆空间
  • 图像处理之HSV颜色空间
  • 【第七天】零基础入门刷题Python-算法篇-数据结构与算法的介绍-一种常见的分治算法(持续更新)
  • Brightness Controller-源码记录
  • 独立开发者常见开发的应用有哪些
  • 正则表达式基础与应用