[SOLVED] stbi_info_from_memory won't recognize data as an image.

Started by mcmacker4, July 17, 2019, 16:32:51

Previous topic - Next topic

mcmacker4

Hi, I'm working on a project written in Kotlin using LWJGL 3.2.2 and Gradle and I need some help.
I'm trying to load texture data from a png located in the resources folder using STBImage. The code is at the bottom.
The thing about this code is that, no matter what I do, it always throws the exception with the message "Image not of any known type or corrupt" and I don't know what I'm doing wrong. And, yes, I made sure that the data stored in the buffer is the actual image. If you turn it into a string and print it you can see the PNG header at the beginning and the IEND chunk at the end. Any ideas why this isn't working?

val id = glGenTextures()
glBindTexture(GL_TEXTURE_2D, id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

Texture::class.java.getResourceAsStream("/textures/$path").use { file ->
    val fileArray = file.readBytes()
    val fileBuffer = ByteBuffer.wrap(fileArray).flip()
    
    if (!stbi_info_from_memory(fileBuffer, IntArray(1), IntArray(1), IntArray(1))) {
        throw Exception(stbi_failure_reason())
    } else {
        MemoryStack.stackPush().use { stack ->
            val xbuff = stack.mallocInt(1)
            val ybuff = stack.mallocInt(1)
            val cbuff = stack.mallocInt(1)
            val imageData = stbi_load_from_memory(fileBuffer, xbuff, ybuff, cbuff, 4)
                ?: throw STBLoadException("STB could not load image from memory.")
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xbuff.get(), ybuff.get(), 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData)
            stbi_image_free(imageData)
        }
    }
}

KaiHH

LWJGL can only work with direct NIO buffers, not ones wrapped around on-heap JVM byte arrays. That is because LWJGL will simply supply the underlying native library with the off-heap virtual pointer address, which does not exist with byte-array-wrapped NIO buffers.

mcmacker4

Quote from: KaiHH on July 17, 2019, 16:35:10
LWJGL can only work with direct NIO buffers, not ones wrapped around on-heap JVM byte arrays. That is because LWJGL will simply supply the underlying native library with the off-heap virtual pointer address, which does not exist with byte-array-wrapped NIO buffers.

That was super helpful, I didn't know you couldn't use array wrapped buffers with LWJGL. I fixed it by allocating a buffer with MemoryUtil.memAlloc() and writing the contents of the array into it. Then freeing the buffer with MemoryUtil.memFree() when no longer necessary.