我正在尝试在Mac OSX上使用JNA直接从Java中使用OpenGL(我已经在Windows和Linux上成功完成了)。我通过JOGL源浏览,但他们使用的CALayers我还不明白。我想尽可能简单地使用NSOpenGLView并将其置于AWT Canvas的顶部。我发现NSWindow使用JNA并添加我创建的NSOpenGLView,它似乎工作,除非我调用[nsOpenGLContext setView]或[nsOpenGLView lockFocus]我得到'无效的drawable'错误。我从Rococoa那里学到了如何使用Java中的ObjectiveC。
以下是一些示例代码:
private static boolean createMac(GL gl, Component c) {
NSAutoreleasePool pool = new NSAutoreleasePool();
pool.alloc();
pool.init();
gl.nsopenglview = new NSOpenGLView();
gl.nsopenglview.alloc();
Pointer ptr = Native.getWindowPointer(findWindow(c));
NSObject nsComponent = new NSObject();
nsComponent.obj = ptr;
Pointer cClass = nsComponent._class();
NSView view = new NSView();
view.alloc();
boolean isView = view.isKindOfClass(cClass);
// JFLog.log("test=" + isView);
if (isView) {
view.dealloc();
view.obj = ptr; //do NOT dealloc this (usually NSWindowViewAWT)
gl.nswindow = view.window();
} else {
view.dealloc();
gl.nswindow = new NSWindow();
gl.nswindow.obj = ptr;
}
NSOpenGLPixelFormat fmt = new NSOpenGLPixelFormat();
fmt.alloc();
fmt.initWithAttributes(new int[] {
NSOpenGLPFAWindow,
// NSOpenGLPFAAccelerated, //is not available on my test system
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAColorSize,24,
NSOpenGLPFADepthSize,16,
0 //zero terminate list
}
);
if (fmt.obj == null) {
JFLog.log("NSOpenGLPixelFormat initWithAttributes failed");
return false;
}
if (gl.nsopenglview != null) {
gl.nsopenglview.initWithFrame(new NSRect(c.getBounds()), fmt);
}
NSView content = gl.nswindow.contentView();
JFLog.log("content view=" + content.obj);
content.addSubview(gl.nsopenglview);
JFLog.log("layered=" + content.wantsLayer());
//use created context
gl.nsopenglcontext = gl.nsopenglview.openGLContext();
//create some resize/move listeners
final GL _gl = gl;
final Component _c = c;
c.addComponentListener(new ComponentListener() {
public void componentResized(ComponentEvent e) {
_gl.nsopenglview.setFrame(new NSRect(_c.getBounds()));
}
public void componentMoved(ComponentEvent e) {
_gl.nsopenglview.setFrame(new NSRect(_c.getBounds()));
}
public void componentShown(ComponentEvent e) {}
public void componentHidden(ComponentEvent e) {}
});
if (api == null) {
api = new GLFuncs();
gl.glLibrary = NativeLibrary.getInstance("OpenGL");
try {
Field fields[] = api.getClass().getFields();
for(int a=0;a<fields.length;a++) {
String name = fields[a].getName();
try {
fields[a].set(api, gl.glLibrary.getFunction(name));
} catch (Throwable t) {
JFLog.log("OpenGL:Warning:Function not found:" + name);
}
}
} catch (Exception e) {
JFLog.log(e);
}
}
pool.release();
return true;
}
我不能在NSOpenGLView中使用drawRect函数,所以我只需要lockFocus,完成后使用gl命令和unlockFocus。但是NSOpenGLContext没有分配视图,并且尝试分配我创建的视图会生成'无效的drawable'。
有什么想法吗?
如果你想要一个完整的工作演示goto http://javaforce.sf.net并下载v7.15.0,在/ jf中运行ant,然后在/ projects / jtest3d中运行,然后执行run.sh(单击GLCanvas测试)。
答案 0 :(得分:0)
我搞定了!问题出在Rococoa(或者可能是JNA中的一个bug)。他们的NSRect结构没有正确传递给[NSOpenGLView initWithFrame]或[NSWindow initWithContentRect]。如果我直接将4个字段(x,y,width,height)传递给函数而不是Structure本身,那么它就可以工作。我还使用[NSObject performSelectorOnMainThread]来确保我在主线程上执行所有GUI内容。
因此可以使用Java中的纯JNA来使用OpenGL。不需要本机代码。
这应该可以在v7.16的javaforce.sf.net中找到,我将在一段时间内发布。
感谢。