Thin multiplatform wrappers for graphics.

Overview

GitHub license

Kotlin Graphics Libraries

Kotlin Multiplatform libraries for graphics.

KGL uses LWJGL for the JVM target and the respective native libraries on the native targets. It provides a thin OOP wrapper with DSLs to make programming with vulkan easier.

You can find some kgl-vulkan samples here and kgl-opengl samples here.

Usage

repositories {
    maven("https://maven.pkg.github.com/Dominaezzz/kgl") {
        credentials {
            username = System.getenv("GITHUB_USER") // Your GitHub username.
            password = System.getenv("GITHUB_TOKEN") // A GitHub token with `read:packages`.
        }
    }
}

dependencies {
    api("com.kgl:kgl-core:$kglVersion")
    api("com.kgl:kgl-glfw:$kglVersion")
    api("com.kgl:kgl-glfw-static:$kglVersion") // For GLFW static binaries
    api("com.kgl:kgl-opengl:$kglVersion")
    api("com.kgl:kgl-vulkan:$kglVersion")
    api("com.kgl:kgl-glfw-vulkan:$kglVersion")
    api("com.kgl:kgl-stb:$kglVersion")
}

Design

The main goal of this library is to hide the verbosity of working with vulkan.

For example in C++, to create a vulkan instance one would have to write code like,

std::vector<std::string> layers = TODO();
std::vector<std::string> extensions = TODO();

VkApplicationInfo applicationInfo = {};
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pNext = nullptr;
applicationInfo.pApplicationName = "Kgl App";
applicationInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.pEngineName = "No Engine yet";
applicationInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
applicationInfo.apiVersion = VK_VERSION_1_1;

VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.pApplicationInfo = &applicationInfo;
createInfo.enabledLayerCount = layers.size();
createInfo.ppEnabledLayerNames = layers.data();
createInfo.enabledExtensionCount = extensions.size();
createInfo.ppEnabledExtensionNames = extensions.data();

VkInstance instance;
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
    throw std::runtime_error("Failed to create instance!");
}

but in Kotlin (with the help of KGL),

val layers: List<String> = TODO()
val extensions: List<String> = TODO()

val instance = Instance.create(layers, extensions) {
    applicationInfo {
        applicationName = "Kgl App"
        applicationVersion = VkVersion(1u, 1u, 0u)
        engineName = "No engine yet"
        engineVersion = VkVersion(1u, 0u, 0u)
        apiVersion = VkVersion(1u, 1u, 0u)
    }
}

To create a device in C++,

uint32_t deviceCount = 1;
VkPhysicalDevice physicalDevice;
vkEnumeratePhysicalDevices(instance, &deviceCount, &physicalDevice);
if (deviceCount < 1) throw std::runtime_error("Failed to find GPU with vulkan support.");

std::vector<VkDeviceQueueCreateInfo> queueCreateInfos(2);

float queuePriority = 1.0f;

VkDeviceQueueCreateInfo& queueCreateInfo1 = queueCreateInfos[0];
queueCreateInfo1.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo1.pNext = nullptr;
queueCreateInfo1.flags = VK_DEVICE_QUEUE_CREATE_PROTECTED;
queueCreateInfo1.queueFamilyIndex = 1;
queueCreateInfo1.queueCount = 1;
queueCreateInfo1.pQueuePriorities = &queuePriority;

VkDeviceQueueCreateInfo& queueCreateInfo2 = queueCreateInfos[1];
queueCreateInfo2.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfo2.pNext = nullptr;
queueCreateInfo2.flags = 0;
queueCreateInfo2.queueFamilyIndex = 2;
queueCreateInfo2.queueCount = 1;
queueCreateInfo2.pQueuePriorities = &queuePriority;

VkPhysicalDeviceFeatures deviceFeatures = {};
deviceFeatures.samplerAnisotropy = VK_TRUE;
deviceFeatures.geometryShader = VK_TRUE;
deviceFeatures.depthClamp = VK_TRUE;

std::vector<std::string> layers = TODO();
std::vector<std::string> extensions = TODO();

VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.pQueueCreateInfos = queueCreateInfos.data();
createInfo.queueCreateInfoCount = queueCreateInfos.size();
createInfo.pEnabledFeatures = &deviceFeatures;
createInfo.enabledExtensionCount = extensions.size();
createInfo.ppEnabledExtensionNames = extensions.data();
createInfo.enabledLayerCount = layers.size();
createInfo.ppEnabledLayerNames = layers.data();

VkDevice device;
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
    throw std::runtime_error("failed to create logical device!");
}

but in Kotlin,

val physicalDevice = instance.physicalDevices.first()

val device = physicalDevice.createDevice(layers, extensions) {
    queues {
        queue(1u, 1.0f) {
            flags = DeviceQueueCreate.PROTECTED
        }

        queue(2u, 1.0f)
    }

    enabledFeatures {
        samplerAnisotropy = true
        geometryShader = true
        depthClamp = true
    }
}

Handles

Every vulkan handle has a class of it's own. The name of the class being the name of the handle without the Vk prefix. Like Instance for VkInstance, CommandBuffer for VkCommandBuffer, etc. All handles keep a reference to their parent, to be able to destroy or free themselves later. Some handles hold a few values from their creation. Like Image has size, layers and format properies.

Structs

Input structs on the other hand have a DSL builder class. Output structs have a corresponding data class.

typedef struct VkLayerProperties {
    char        layerName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
    uint32_t    implementationVersion;
    char        description[VK_MAX_DESCRIPTION_SIZE];
} VkLayerProperties;
data class LayerProperties(
    val layerName: String,
    val specVersion: VkVersion,
    val implementationVersion: UInt,
    val description: String
)

Enums

Enums are represented with a kotlin enum. If the enum is a part a bitmask then it extends VkFlag<T> to allow for type-safe bit fiddling.

typedef VkFlags VkCullModeFlags;
typedef enum VkCullModeFlagBits {
    VK_CULL_MODE_NONE = 0,
    VK_CULL_MODE_FRONT_BIT = 0x00000001,
    VK_CULL_MODE_BACK_BIT = 0x00000002,
    VK_CULL_MODE_FRONT_AND_BACK = 0x00000003,
} VkCullModeFlagBits;

VkCullModeFlags flags = VK_CULL_MODE_FRONT_BIT | VK_CULL_MODE_BACK_BIT;
enum class CullMode : VkFlag<CullMode> {
    NONE,
    FRONT,
    BACK
}

val flags: VkFlag<CullMode> = CullMode.FRONT or CullMode.BACK

Although this does mean that bitwise operations create new objects. Once inline enums are implemented in Kotlin, we'll get the type-safety without the allocations.

Commands

Every command's function pointer has been explicitly loaded using vkGetDeviceProcAddr and vkGetInstanceProcAddr for optimal command calling performance. This also means you don't need to have the Vulkan SDK installed to get started with kgl-vulkan.

At the moment every core and extension (non-platform specific) command has been implemented as a member function/property of a handle class. In most cases it is a member of the last of the first consecutive handles in the parameter list. In other cases, it is moved to a handle class that makes the most sense.

VkResult vkMapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData);
fun DeviceMemory.map(offset: ULong, size: ULong, flags: VkFlag<MemoryMap>? = null): IoBuffer

or

VkResult vkEnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
val Instance.physicalDevices: List<PhysicalDevice>

GLFW Example

val window = Window(1080, 720, "Sample!") {
    clientApi = ClientApi.None
    resizable = false
    visible = true
}

val (width, height) = window.size
val mode = Glfw.primaryMonitor!!.videoMode
window.position = ((mode.width - width) / 2) to ((mode.height - height) / 2)

Limitations

  • OpenGL is only supported on native targets.
  • Only core OpenGL is supported and is loaded on the first gl function call.
  • Platform specific extensions have not been implemented yet. Mostly because of this.
  • Support for pNext has not been implemented yet.
  • Some parts of the api that use an IoBuffer have not yet been implemented as it requires bespoke design.
  • Documentation is partially generated.
  • Until the bulk of library is under codegen, only version 1.1.92 will be supported.
Comments
  • Best approach for a kgl-math library?

    Best approach for a kgl-math library?

    • API largely on GLM, with some Kotlinic modifications to the naming
    • Native library wrapped by Kotlin classes should work well
    • glm is C++-only, so maybe cglm? Although from their readme, they seem to be missing some features of glm atm. Not sure if unaligned vectors and matrices are important.
    opened by nlbuescher 24
  • add return values to global callback setters

    add return values to global callback setters

    Glfw.setErrorCallback, Glfw.setJoystickCallback, and Glfw.setMonitorCallback (the last one is needed for imgui-docking) were not returning the previous callbacks. I missed those with the last fix, and this time I double checked that all functions named set…Callback have a return type.

    opened by nlbuescher 8
  • move to new maven repository due to Bintray shutdown

    move to new maven repository due to Bintray shutdown

    kgl is currently unavailable as a maven/gradle dependency because of this

    also can you push a new release while you're at it ? still waiting for #34 to become available

    opened by LastExceed 5
  • Fix issue where setting callback on GLFW Window doesn't return the previous callback

    Fix issue where setting callback on GLFW Window doesn't return the previous callback

    This is relevant and important because it directly affects the ability of the imgui glfw implementation to function. The C++ version takes the returned callbacks and stores them to be called alongside the callbacks it installs. Not returning the previous callbacks results in two possible scenarios:

    1. ImGuiGlfw is initialized with callbacks and mouse events are eaten by ImGui, disabling mouse event processing by the application proper.
    2. ImGuiGlfw is initialized without callbacks and key events are not processed by ImGui, preventing text entry in ImGui.

    This is the first of two updates to fix the issue. Part two will actually utilize the prev... callback references in ImGuiGLFW and set them to the proper values, but it understandably depends on this change.

    I've already made the changes and tested them locally by publishing to the local maven repo. Please let me know if I've missed anything in my attempts to fix this.

    opened by nlbuescher 5
  • kgl-opengl on macOS creates 2.1 context instead of 4.1 context by default

    kgl-opengl on macOS creates 2.1 context instead of 4.1 context by default

    kgl-opengl currently can only create an OpenGL context up version 2.1, because Apple. Platform lib only supports up to 3.2+ (no 4), but there's nothing to be done about that. Calling gl functions from 4+ throws NullPointerException because the function loader can't find them.

    opened by nlbuescher 5
  • can't resolve kgl-glfw-static library

    can't resolve kgl-glfw-static library

    Could not resolve com.kgl:kgl-glfw-static:0.1.11.

    Using dependencies block from your imgui project. commenting the single glfw-static dependency solves it.

    
    val imguiVersion = "0.1.9"
    val kglVersion = "0.1.11"
    
    repositories {
        mavenCentral()
    
        maven ("https://maven.pkg.github.com/Dominaezzz/kotlin-imgui") {
            credentials {
                username = project.findProperty("gpr.user") as String ?: System.getenv("GITHUB_USER")
                password = project.findProperty("gpr.password") as String ?: System.getenv("GITHUB_TOKEN")
            }
        }
    }
    
    dependencies {
        implementation(kotlin("stdlib"))
    
        // Dear::ImGui bindings for kotlin
        implementation("com.kotlin-imgui:imgui:$imguiVersion")
        implementation("com.kotlin-imgui:imgui-glfw:$imguiVersion")
        implementation("com.kotlin-imgui:imgui-opengl:$imguiVersion")
    
        // For jvm binaries
        implementation("com.kotlin-imgui:cimgui-jvmlinuxx64:$imguiVersion")
        implementation("com.kotlin-imgui:cimgui-jvmmacosx64:$imguiVersion")
        implementation("com.kotlin-imgui:cimgui-jvmmingwx64:$imguiVersion")
    
        // Optional
        implementation("com.kgl:kgl-glfw:$kglVersion")
        implementation("com.kgl:kgl-glfw-static:$kglVersion")
        implementation("com.kgl:kgl-opengl:$kglVersion")
        implementation("com.kgl:kgl-stb:$kglVersion")
    }
    
    opened by T3sT3ro 4
  • can't switch from fullscreen to windowed mode

    can't switch from fullscreen to windowed mode

    to switch to windowed mode the monitor ptr must be set to null, however the monitor param of kgl's window.setMonitor() function is non-nullable, making this operation impossible

    opened by LastExceed 3
  • Can't compile with version kgl-opengl 0.1.9-dev-6, compiler crash

    Can't compile with version kgl-opengl 0.1.9-dev-6, compiler crash

    Will have to test more in isolation (mini project), but there seems to be an issue somewhere with the conversion from Boolean to UByte. Code works fine with kgl-opengl 0.1.9-dev-5 (ie before the addition of nice_opengl changes.

    e: Compilation failed: actual type is kotlin.Boolean, expected kotlin.UByte
    
     * Source files: 
     * Compiler version info: Konan: 1.3.61 / Kotlin: 1.3.60
     * Output kind: PROGRAM
    
    e: java.lang.IllegalStateException: actual type is kotlin.Boolean, expected kotlin.UByte
    e: Compilation failed: actual type is kotlin.Boolean, expected kotlin.UByte
    
    	at org.jetbrains.kotlin.backend.konan.BoxingKt.getTypeConversionImpl(Boxing.kt:40)
    	at org.jetbrains.kotlin.backend.konan.BoxingKt.getTypeConversion(Boxing.kt:28)
    	at org.jetbrains.kotlin.backend.konan.lower.AutoboxingTransformer.adaptIfNecessary(Autoboxing.kt:161)
    	at org.jetbrains.kotlin.backend.konan.lower.AutoboxingTransformer.useAs(Autoboxing.kt:125)
    	at org.jetbrains.kotlin.backend.konan.lower.AutoboxingTransformer.visitCall(Autoboxing.kt:200)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:170)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl.accept(IrCallImpl.kt:89)
    	at org.jetbrains.kotlin.ir.expressions.IrExpression$DefaultImpls.transform(IrExpression.kt:28)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase.transform(IrExpressionBase.kt:24)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrCallWithIndexedArgumentsBase.transformChildren(IrCallWithIndexedArgumentsBase.kt:70)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer.visitFunctionAccess(AbstractValueUsageTransformer.kt:91)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:169)
    	at org.jetbrains.kotlin.backend.konan.lower.AutoboxingTransformer.visitCall(Autoboxing.kt:205)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:170)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitCall(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl.accept(IrCallImpl.kt:89)
    	at org.jetbrains.kotlin.ir.expressions.IrExpression$DefaultImpls.transform(IrExpression.kt:28)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase.transform(IrExpressionBase.kt:24)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl.transformChildren(IrVariableImpl.kt:93)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer.visitVariable(AbstractValueUsageTransformer.kt:174)
    	at org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer.visitVariable(AbstractValueUsageTransformer.kt:32)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitVariable(IrElementTransformerVoid.kt:85)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitVariable(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl.accept(IrVariableImpl.kt:86)
    	at org.jetbrains.kotlin.ir.declarations.IrDeclaration$DefaultImpls.transform(IrDeclaration.kt:42)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase.transform(IrDeclarationBase.kt:27)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl.transformChildren(IrBlockBodyImpl.kt:49)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer.visitBlockBody(AbstractValueUsageTransformer.kt:107)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlockBody(IrElementTransformerVoid.kt:97)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitBlockBody(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl.accept(IrBlockBodyImpl.kt:40)
    	at org.jetbrains.kotlin.ir.expressions.IrBody$DefaultImpls.transform(IrBody.kt:24)
    	at org.jetbrains.kotlin.ir.expressions.IrBlockBody$DefaultImpls.transform(IrBody.kt)
    	at org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl.transform(IrBlockBodyImpl.kt:26)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase.transformChildren(IrFunctionBase.kt:77)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.backend.common.AbstractValueUsageTransformer.visitFunction(AbstractValueUsageTransformer.kt:248)
    	at org.jetbrains.kotlin.backend.konan.lower.AutoboxingTransformer.visitFunction(Autoboxing.kt:77)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:55)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:56)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitSimpleFunction(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl.accept(IrFunctionImpl.kt:90)
    	at org.jetbrains.kotlin.ir.declarations.IrDeclaration$DefaultImpls.transform(IrDeclaration.kt:42)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase.transform(IrDeclarationBase.kt:27)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl.transformChildren(IrClassImpl.kt:100)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.transformChildrenVoid(IrElementTransformerVoid.kt:280)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.transformChildren(IrElementTransformerVoid.kt:25)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitDeclaration(IrElementTransformerVoid.kt:46)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:49)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:50)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid.visitClass(IrElementTransformerVoid.kt:24)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl.accept(IrClassImpl.kt:89)
    	at org.jetbrains.kotlin.ir.declarations.IrDeclaration$DefaultImpls.transform(IrDeclaration.kt:42)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase.transform(IrDeclarationBase.kt:27)
    	at org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl.transformChildren(IrFileImpl.kt:71)
    	at org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoidKt.transformChildrenVoid(IrElementTransformerVoid.kt:285)
    	at org.jetbrains.kotlin.backend.konan.lower.Autoboxing.lower(Autoboxing.kt:48)
    	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$makeIrFilePhase$1.invoke(PhaseBuilders.kt:173)
    	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$makeIrFilePhase$1.invoke(PhaseBuilders.kt:171)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:28)
    	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$performByIrFile$1.invoke(PhaseBuilders.kt:144)
    	at org.jetbrains.kotlin.backend.common.phaser.PhaseBuildersKt$performByIrFile$1.invoke(PhaseBuilders.kt:136)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:28)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.konan.ToplevelPhasesKt$dependenciesLowerPhase$1.invoke(ToplevelPhases.kt:319)
    	at org.jetbrains.kotlin.backend.konan.ToplevelPhasesKt$dependenciesLowerPhase$1.invoke(ToplevelPhases.kt:305)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:28)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.common.phaser.CompositePhase.invoke(PhaseBuilders.kt:28)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper$runBody$1.invoke(CompilerPhase.kt:128)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.downlevel(CompilerPhase.kt:24)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.runBody(CompilerPhase.kt:127)
    	at org.jetbrains.kotlin.backend.common.phaser.AbstractNamedPhaseWrapper.invoke(CompilerPhase.kt:105)
    	at org.jetbrains.kotlin.backend.common.phaser.CompilerPhaseKt.invokeToplevel(CompilerPhase.kt:42)
    	at org.jetbrains.kotlin.backend.konan.KonanDriverKt.runTopLevelPhases(KonanDriver.kt:27)
    	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:74)
    	at org.jetbrains.kotlin.cli.bc.K2Native.doExecute(K2Native.kt:34)
    	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
    	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
    	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
    	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:82)
    	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:50)
    	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:215)
    	at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:207)
    	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:225)
    	at org.jetbrains.kotlin.cli.bc.K2Native$Companion$main$1.invoke(K2Native.kt:222)
    	at org.jetbrains.kotlin.util.UtilKt.profileIf(Util.kt:27)
    	at org.jetbrains.kotlin.util.UtilKt.profile(Util.kt:21)
    	at org.jetbrains.kotlin.cli.bc.K2Native$Companion.main(K2Native.kt:224)
    	at org.jetbrains.kotlin.cli.bc.K2NativeKt.main(K2Native.kt:304)
    	at org.jetbrains.kotlin.cli.utilities.MainKt.main(main.kt:16)
    
    opened by nlbuescher 3
  • GLFW KeyboardKey `value` and `from` are internal preventing easy conversion from GLFW to custom class

    GLFW KeyboardKey `value` and `from` are internal preventing easy conversion from GLFW to custom class

    This also applies to MouseButton. Having the value be inaccessible makes it very difficult to convert the library-specific KeyboardKey into a library-agnostic custom class. Making value and from public would solve the issue.

    opened by nlbuescher 3
  • Could not find io.ktor:ktor-io:1.4.0.

    Could not find io.ktor:ktor-io:1.4.0.

    I am using the OpenGL sample and I edited it to use a more recent version of kotlin

    image

    Here is my build.gradle.kts code:

    import org.gradle.internal.os.OperatingSystem;
    import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
    
    plugins {
        kotlin("multiplatform") version "1.6.21"
    }
    
    repositories {
        maven("https://maven.pkg.github.com/Dominaezzz/kgl") {
            credentials {
                username = "USERNAME"
                password = "TOKEN"
            }
        }
    }
    
    val kglVersion = "0.1.11"
    
    kotlin {
        val os = OperatingSystem.current()
    
        if (os.isWindows) mingwX64()
        if (os.isLinux) linuxX64()
        if (os.isMacOsX) macosX64()
    
        targets.withType<KotlinNativeTarget> {
            binaries {
                executable {
                    entryPoint = "main"
                }
            }
            compilations {
                "main" {
                    defaultSourceSet {
                        kotlin.srcDir("src/main/kotlin")
                        resources.srcDir("src/main/resources")
                    }
                    dependencies {
                        implementation("com.kgl:kgl-glfw:$kglVersion")
                        implementation("com.kgl:kgl-glfw-static:$kglVersion")
                        implementation("com.kgl:kgl-opengl:$kglVersion")
                        implementation("com.kgl:kgl-stb:$kglVersion")
                    }
                }
                "test" {
                    defaultSourceSet {
                        kotlin.srcDir("src/test/kotlin")
                        resources.srcDir("src/test/resources")
                    }
                }
            }
        }
    
        sourceSets {
            // Note: To enable common source sets please comment out "kotlin.import.noCommonSourceSets" property
            // in gradle.properties file and re-import your project in IDE.
        }
    
        sourceSets.all {
            languageSettings.apply {
                enableLanguageFeature("InlineClasses")
                optIn("kotlin.ExperimentalUnsignedTypes")
            }
        }
    }
    
    opened by real-fluidity 2
  • Static glfw

    Static glfw

    At the moment, glfw is setup for dynamic linking. So users of kgl-glfw need to have glfw installed on their system. In most cases, glfw 3.2.1 has to be built from source and is not available from a package manager, this is not very beginner friendly :). So I want to bundle a static build of glfw with the KLIBs, so that way, they are self-contained and link automatically. I'm currently looking at the implications of doing it this way.

    opened by Dominaezzz 2
  • What about updates and development?

    What about updates and development?

    Hello, you doing awesome work, but i have several questions:

    • Why you stop develop this library?
    • Why you support only desktop platforms? (A lot of people use kotlin for mobile instead desktop development)
    • Can i help you develop your library? (For example you have a vision of project but have not enough time for development) Thank you for your job!
    opened by Sorrowful-free 6
  • GLFW and multi-threading

    GLFW and multi-threading

    As mentioned in #27

    Some concerns:

    • How does having a @ThreadLocal Glfw object impact multithreaded applications?
    • Should GLFW calls be limited to only the "main" thread (and throw an exception otherwise)?
    • How is multithreadedness handled in a C/C++ application with GLFW?
    question 
    opened by nlbuescher 0
  • kgl-stb: cstb.stbi_load and STBImage.load both crash on Windows 10

    kgl-stb: cstb.stbi_load and STBImage.load both crash on Windows 10

    Error code -1073741819. Googling this suggests a file system error, but I have no idea. Trying any of the suggested fixes yields no results.

    I've copied the entire stb_image.h into a cinterop def with the following headings, and it works fine, but using kgl-stb makes it crash:

    excludedFunctions = stbi__err
    compilerOpts = -DSTB_IMAGE_IMPLEMENTATION
    
    opened by nlbuescher 3
  • New Buffer classes

    New Buffer classes

    Introduce new buffer classes independent of kotlinx.io. This will allow kgl to target more platforms and smooth out some APIs that were made awkward by shoving IoBuffer into them.

    • [x] ByteBuffer
    • [ ] ShortBuffer
    • [ ] IntBuffer
    • [ ] LongBuffer

    Fixes #4 .

    opened by Dominaezzz 0
  • KGL-Math

    KGL-Math

    Kotlinic basic implementation of vector and 4 by 4 matrix types to allow for basic 3d transformation.

    • [x] Vec2 / MutableVec2
    • [x] Vec3 / MutableVec3
    • [x] Vec4 / MutableVec4
    • [x] Mat4 / MutableMat4
    opened by nlbuescher 22
  • `kgl-stb` doesn't not have a

    `kgl-stb` doesn't not have a "load from file" function

    unsigned char* stbi_load(const char* filename, int* x, int* y, int* channels_in_file, int desired_channels)
    

    or equivalent

    fun STBImage.loadFrom(filename: String, desiredChannels: Int? = null)
    

    are not present in kgl-stb, and at this point, there is no good way to interact with files using kotlinx-io because of the massive restructuring they're doing right now.

    The cinterop def explicitly defines STB_NO_STDIO, which prevents the generation of stbi_load, but stbi_load works fine with cinterop. What was the reason for defining STB_NO_STDIO?

    opened by nlbuescher 2
Owner
Dominic Fischer
Computer Science Graduate from The University Of Manchester. Kotlin Developer. Android Developer.
Dominic Fischer
Component Box - a multiplatform server-driven UI framework

Component Box · Component Box is a multiplatform server-driven UI framework. Learn how to use Component Box in your project. Installation implementati

Dropbox 216 Dec 31, 2022
Kotter - aims to be a relatively thin, declarative, Kotlin-idiomatic API that provides useful functionality for writing delightful console applications.

Kotter (a KOTlin TERminal library) aims to be a relatively thin, declarative, Kotlin-idiomatic API that provides useful functionality for writing delightful console applications.

Varabyte 348 Dec 21, 2022
Preference wrappers for primitive types for Android

Typed Preferences This library for Android provides classes which allow to store and retrieve settings from the preferences. There is an individual cl

Tobias Preuss 189 Nov 25, 2022
Kompose wrappers for material-components-web

Kompose Material Design Components (KMDC) A set of kotlin wrappers over [email protected] library providing Jetbrains Compose DSL for bui

Martynas Petuška 82 Jan 1, 2023
A Gradle plugin for generating multi-version packet wrappers for Minecraft: JE

tinyprotocol A Gradle plugin for generating multi-version packet class wrappers for Minecraft: Java Edition. Usage plugins { id("me.kcra.tinyproto

Matouš Kučera 2 Feb 21, 2022
Candroid does things different. The Candroid app store is a library of APK client wrappers (F-Droid, APKPure, etc.) For the main Candroid app store, try visiting the Candroid Market.

Candroid App Store Candroid does things different. The Candroid app store is a library of APK client wrappers (F-Droid, APKPure, etc.) For the main Ca

Sean P. Myrick V19.1.7.2 4 Dec 22, 2022
A set of web-based tools for generating graphics and other assets that would eventually be in an Android application's res/ directory.

Android Asset Studio Open the Android Asset Studio See the older version if you're having trouble with the new version A web-based set of tools for ge

Roman Nurik 6.3k Dec 31, 2022
Scalable vector graphics for Android

Sharp Sharp is a Scalable Vector Graphics (SVG) implementation for Android. It facilitates loading vector graphics as SharpDrawables, and can effectiv

Pixplicity 1k Dec 31, 2022
YBKChart is a library of 3D graphics charts for Android. 📊

YBKChart is a library of 3D graphics charts for Android. ?? For more information, see the Wiki. Chart List Pie Chart Download Use gradle. rep

ByungKwan Yun 10 Jun 19, 2022
Polytech computer graphics couerse code scam script

Js-code-parser Polytech computer graphics couerse code scam script Копируйте строку скрипта с дебаггера с странички лабы. Вставляйте в файлик test.txt

Daniil Bakin 2 Dec 18, 2022
Linux GUI for Kuri's userspace tablet drivers. Supports non-wacom (XP-Pen, Huion, Gaomon) graphics tablets and pen displays

Kuri's Userspace tablet driver utility (GUI) This is a new GUI implementation for the userland driver I've written here: https://github.com/kurikaesu/

Aren Villanueva 12 Jan 4, 2023
A set of APIs to manipulate graphics paths on Android

Pathway Pathway is an Android library that provides new functionalities around the graphics Path API. Pathway is compatible with API 21+. Maven reposi

Romain Guy 147 Dec 17, 2022
Primitive OpenGL (ES) based graphics library and engine for Android development.

Parrot Primitive OpenGL (ES) based graphics library and engine for Android development. Parrot makes Android core graphics simpler, giving you the fea

null 1 Dec 30, 2021
Dokka plugin to render Mermaid graphics, from your code comments to your Dokka documentation.

Dokka plugin to render Mermaid graphics, from your code comments to your Dokka documentation.

Grégory Lureau 24 Jan 7, 2023
Bring together all of the remarkable Computer Graphics Algorithms in one place 🚀

Compose Computer Graphics Playground ?? "There was an idea to bring together all of the remarkable Computer Graphics Algorithms in one place. And keep

Jaseemakhtar 162 Dec 27, 2022
Turtle Graphics 🐢 implementation for Android Platform with Code Editor, Preview Screen and packages

Turtle Graphics Download Turtle is an Android Application inspired from the original Turtle Graphics and Logo, Logo is an educational programming lang

Amr Hesham 15 Dec 30, 2022
Multiplatform UI DSL with screen management in common code for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin widgets This is a Kotlin MultiPlatform library that provides declarative UI and application screens management in common code. You can i

IceRock Development 320 Dec 30, 2022
Odyssey it's a declarative multiplatform navigation library for Multiplatform Compose

Odyssey Odyssey it's a declarative multiplatform navigation library for Multiplatform Compose ?? WARNING! It's an early preview, so you use it with yo

Alex 168 Jan 5, 2023
Multiplatform coroutine-based HTTP client wrapper for Kotlin

networkinkt This is a lightweight HTTP client for Kotlin. It relies on coroutines on both JS & JVM platforms. Here is a simple GET request: val text =

Egor Zhdan 31 Jul 27, 2022
Mobile client for official Nextcloud News App written as Kotlin Multiplatform Project

Newsout Android and iOS mobile client for Nextcloud news App. The Android client is already available to download in the Play Store. F-Droid and Apple

Simon Schubert 118 Oct 3, 2022