LWJGL+GLFW

Skia 有多个库可供选择,包括 OpenGL 和 Vulkan,作为后端。 在本例中,我们将使用一个名为 LWJGL 的库作为 JVM 中 OpenGL 和窗口显示的提供程序。

https://www.lwjgl.org/

这是一个游戏库,所以它有点大。 只要你能使用 OpenGL (GLFW),我认为你可以在任何库中实现它而无需太多更改。

项目准备情况

IntelliJ IDEA

IntelliJ IDEA 2024.1 (Community Edition)
Build #IC-241.14494.240, built on March 28, 2024
Runtime version: 17.0.10+8-b1207.12 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 14.4.1
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 10
Metal Rendering is ON
Registry:
  ide.experimental.ui=true
Non-Bundled Plugins:
  com.c5inco.modifiers (1.0.15)
  com.intellij.ideolog (222.3.2.0)
  com.jetbrains.space (241.14494.150)
  izhangzhihao.rainbow.brackets (2024.2.2-241)
  com.github.lppedd.kotlin-additional-highlighting (0.2.2)
  com.aiwan.compose (1.0.4)
  org.jetbrains.android (241.14494.240)
  androidx.compose.plugins.idea (241.14494.158)
  org.jetbrains.compose.desktop.ide (1.6.2)
Kotlin: 241.14494.240-IJ

创建KotlinSkiaTest

在这里插入图片描述

结构

❯ tree KotlinSkiaTest
KotlinSkiaTest
├── build.gradle.kts
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
└── src
    ├── main
    │   ├── kotlin
    │   │   └── hello_skiko.kt
    │   └── resources
    └── test
        ├── kotlin
        └── resources

10 directories, 8 files

demo

build.gradle.kts

接下来,让我们使窗口可见。 首先,我们将介绍 LWJGL 和 Skiko。

LWJGL 和 Skiko releases

https://github.com/JetBrains/skiko/releases
https://mvnrepository.com/artifact/org.lwjgl/lwjgl

配置
❯ cat build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.9.23"
    // id("org.jetbrains.compose") version "1.0.0"
}

group = "org.forever"
version = "1.0-SNAPSHOT"

val osName: String = System.getProperty("os.name")

val targetOs = when {
    osName == "Mac OS X" -> "macos"
    osName.startsWith("Win") -> "windows"
    osName.startsWith("Linux") -> "linux"
    else -> error("Unsupported OS: $osName")
}

val osArch = System.getProperty("os.arch")
var targetArch = when (osArch) {
    "x86_64", "amd64" -> "x64"
    "aarch64" -> "arm64"
    else -> error("Unsupported arch: $osArch")
}

val skikoVersion = "0.7.9" // or any more recent version
val skikoTarget = "${targetOs}-${targetArch}"
val lwjglVersion = "3.3.3"


val os = when {
    osName == "Mac OS X" -> "macos"
    osName == "Linux" -> "linux"
    osName.startsWith("Win") -> "windows"
    else -> throw Error("Unknown OS $osName")
}
println("osName = $osName targetOs = $targetOs os = $os")
repositories {
    mavenCentral()
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
    maven("https://packages.jetbrains.team/maven/p/skija/maven")
    google()
}


dependencies {
    testImplementation(kotlin("test"))
    implementation("org.jetbrains.skiko:skiko-awt-runtime-$skikoTarget:$skikoVersion")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1")

    implementation("org.lwjgl:lwjgl:${lwjglVersion}")
    implementation("org.lwjgl:lwjgl-glfw:${lwjglVersion}")
    implementation("org.lwjgl:lwjgl-opengl:${lwjglVersion}")
    implementation("org.lwjgl:lwjgl:${lwjglVersion}:natives-$os-$targetArch")
    implementation("org.lwjgl:lwjgl-glfw:${lwjglVersion}:natives-$os-$targetArch")
    implementation("org.lwjgl:lwjgl-opengl:${lwjglVersion}:natives-$os-$targetArch")
}

tasks.test {
    useJUnitPlatform()
}

kotlin {
    jvmToolchain(17)
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "17"
}

hello_skiko.kt

package org.forever

import org.jetbrains.skia.*
import org.lwjgl.glfw.GLFW.*
import org.lwjgl.opengl.GL
import org.lwjgl.opengl.GL11

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
fun main() {
    /*val paintGreen = Paint().apply { color = 0xFF8BC34A.toInt() }
    canvas.drawCircle(100f, 100f, 40f, paintGreen)

    val paintYellow = Paint().apply { color = 0xFFFFEB3B.toInt() }
    canvas.drawCircle(200f, 100f, 40f, paintYellow)

    val paintRed = Paint().apply { color = 0xFFF44336.toInt() }
    canvas.drawCircle(300f, 100f, 40f, paintRed)*/
    val width = 640
    val height = 480

    glfwInit()
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE)
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE)
    val windowHandle = glfwCreateWindow(width, height, "Flume", 0, 0)
    glfwMakeContextCurrent(windowHandle)
    glfwSwapInterval(1)
    glfwShowWindow(windowHandle)


    GL.createCapabilities()

    val context = DirectContext.makeGL()

    val fbId = GL11.glGetInteger(0x8CA6)
    val renderTarget =
        BackendRenderTarget.makeGL(width, height, 0, 8, fbId, FramebufferFormat.GR_GL_RGBA8)

    val surface = Surface.makeFromBackendRenderTarget(context,
        renderTarget,
        SurfaceOrigin.BOTTOM_LEFT,
        SurfaceColorFormat.RGBA_8888,
        ColorSpace.sRGB)!!

    val canvas = surface.canvas

    while (!glfwWindowShouldClose(windowHandle)) {

        val paintGreen = Paint().apply { color = 0xFF8BC34A.toInt() }
        canvas.drawCircle(100f, 100f, 40f, paintGreen)

        val paintYellow = Paint().apply { color = 0xFFFFEB3B.toInt() }
        canvas.drawCircle(200f, 100f, 40f, paintYellow)

        val paintRed = Paint().apply { color = 0xFFF44336.toInt() }
        canvas.drawCircle(300f, 100f, 40f, paintRed)

        context.flush()
        glfwSwapBuffers(windowHandle)
        glfwPollEvents()
    }
}

运行结果

在这里插入图片描述

仓库

https://github.com/forevermgg/KotlinSkiaTest

注意事项

线程错误

Please run the JVM with -XstartOnFirstThread. This check may be disabled with Configuration.GLFW_CHECK_THREAD0.
在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐