Why can't I get correct openGL readings using java.lang.foreign on glGetIntegerv?

Just trying the new feature java.lang.foreign to improve JME3 env settings.
I can read GLFW correctly, but got dificulty reading glGetString.
the reading should sth bigger than 12, but it seems no reading comes to the pointer.
anyone can help me ?

import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SegmentAllocator;
import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author ray
 */
public class JavaApplication1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int ia = 0x8A2B;
        Linker linker = Linker.nativeLinker();
        try (Arena arena = Arena.ofConfined()) {
            SymbolLookup libglfw = SymbolLookup.libraryLookup("libglfw.so", arena);
            MemorySegment glfwGetString = libglfw.findOrThrow("glfwGetVersionString");            
            SymbolLookup libgl = SymbolLookup.libraryLookup("libGL.so", arena);
            MemorySegment glGetString = libgl.findOrThrow("glGetIntegerv");            
            
            MemorySegment glvender = arena.allocate(ValueLayout.JAVA_INT);
            MethodHandle glfwgetversion = linker.downcallHandle(glfwGetString, FunctionDescriptor.of(ValueLayout.ADDRESS));            
            MethodHandle glget = linker.downcallHandle(glGetString, FunctionDescriptor.ofVoid(ValueLayout.JAVA_INT,ValueLayout.ADDRESS));
            
            MemorySegment ptr = (MemorySegment)glfwgetversion.invoke();
            SymbolLookup stdlib = linker.defaultLookup();
            MethodHandle strlen = linker.downcallHandle(stdlib.findOrThrow("strlen"), FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
            long len = (long)strlen.invokeExact(ptr); // 5
            System.out.println(len);
            MemorySegment ptrn = ptr.reinterpret(len+1);
            String strt = ptrn.getString(0);
            System.out.println(strt);
            
            
            //GL_MAX_VERTEX_UNIFORM_BLOCKS
            //data returns one value, the maximum number of uniform blocks per vertex shader. 
            //The value must be at least 12. See glUniformBlockBinding
            glget.invoke(0x8A2B,glvender);  //GL_MAX_VERTEX_UNIFORM_BLOCKS      0x8A2B
            System.out.println("MAX:"+glvender.getAtIndex(ValueLayout.JAVA_INT, 0));
        } catch (Throwable ex) {
            Logger.getLogger(JavaApplication1.class.getName()).log(Level.SEVERE, null, ex);
        }// TODO code application logic here
    }

output

46
3.2.1 Wayland EGL clock_gettime /dev/js shared
MAX:0
BUILD SUCCESSFUL (total time: 0 seconds)

System:
Linux, pre-installed glfw with : apt-get install glfw3
netbeans 23
open JDK 23.1.17
ANT project, (do not use gradle project, gradle only support jdk 22)
menu:
run → set project configuration->customize-> RUN,
set VM options: --enable-native-access=ALL-UNNAMED

future thinking:
With new foreign package , we can setup environment as we wish like choosing in multi-monitor system. or better interactive with GL or replace lwjgl with our own code.

I could be wrong, but don’t you have to i initialze gl first? And probably create a context first.

2 Likes

:sweat_smile:
I’ll try