我正在尝试在Mac上使用JNA直接从Java使用OpenGL (我已经在Windows和Linux上成功地做到了这一点)。我浏览过JOGL源码,但他们使用的是CALayers,我还不明白。我只想简单地使用NSOpenGLView,如果可能的话,把它放在AWT画布上。我使用JNA找到NSWindow并添加我创建的NSOpenGLView,它似乎可以工作,除非当我调用nsOpenGLContext setView或nsOpenGLView lockFocus时,我得到一个'invalid 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没有分配视图,尝试分配我创建的视图会生成“无效的可绘制”。
有什么想法吗?
如果您想要完整的工作演示,请转到http://javaforce.sf.net并下载v7.15.0,在/jf中运行ant,然后在/projects/jtest3d中运行ant,然后执行run.sh (单击GLCanvas测试)。
发布于 2014-06-06 08:41:44
我让它工作了!问题出在Rococoa (或者可能是JNA中的bug )。它们的NSRect结构未正确传递给NSOpenGLView initWithFrame或NSWindow initWithContentRect。如果我将4个字段(x,y,width,height)直接传递给函数,而不是结构本身,那么它就可以工作。我还使用了NSObject performSelectorOnMainThread来确保我在主线程上做所有的图形用户界面的事情。
因此,可以使用来自Java的纯JNA使用OpenGL。不需要本机代码。
这应该在我的javaforce.sf.net 7.16版本中可用,我将在稍后发布。
谢谢。
https://stackoverflow.com/questions/23964998
复制相似问题