我知道已经多次询问并没有明确答案,我已经向nVIDIA提交了一个错误。但是,我仍然在寻找比在Prism-D3D引擎中启动JavaFX更好的解决方法(它可以立即通过nVIDIA创建后续的OpenGL上下文)。
环境:
经过测试并失败:
API失败:
解决方法:
我将问题解决为一个非常简单的示例,调用realtech-vr OpenGL Extension Viewer(用.NET编写)。里面有一个原生的“infogl.dll”,它读取GL信息,显然在oevClientInitialize之后激活了Optimus。
奇怪的是,调用infogl.dll的最简单的控制台程序可以工作:
Win32.oevSetDriverVersion("10.18.10.3621", 2176);
Win32.oevClientLoadDatabase(File.ReadAllText("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml"));
Win32.oevClientInitialize();
for (var i = 0; i <= 9; i++)
{
var tree = Marshal.PtrToStringAnsi(Win32.oevClientGetCapsAndExtTree(i));
Console.WriteLine(tree.Split('\n').First(ln => ln.Contains("text_id=\"357\"")));
}
Console.ReadLine();
但JNA 中Java中的相同代码不是:
infogl.INSTANCE.oevSetDriverVersion("10.18.10.3621", 2176);
String extXml = null;
try {
extXml = new String(
Files.readAllBytes(Paths.get("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml")),
"UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
infogl.INSTANCE.oevClientLoadDatabase(extXml);
infogl.INSTANCE.oevClientInitialize();
for (int i = 0; i <= 9; i++)
{
String tree = infogl.INSTANCE.oevClientGetCapsAndExtTree(i);
System.out.println(Arrays.asList(tree.split("\\n")).first(ln -> ln.contains("text_id=\"357\"")));
}
它与可执行文件名“java”无关 - 我试过了。
JavaFX D3D解决方案不合适,因为它将AMD Radeon芯片的OpenGL FPS降低了一半 - 我认为在nVIDIA芯片上必须同样糟糕,这就是为什么我试图让它与ES2管道一起工作。
答案 0 :(得分:0)
从.NET启动JVM显然有效(通过jni4net)。它在JavaFX结束时通过。
在nvoglv64.dll中崩溃using net.sf.jni4net;
using net.sf.jni4net.utils;
...
public static void Main(string[] args)
{
InitializeOpenGL();
var setup = new BridgeSetup();
setup.AddClassPath(@"C:\Program Files\Java\jdk1.8.0_11\demo\javafx_samples\Modena.jar");
setup.AddJVMOption("-Dprism.order=es2");
setup.AddJVMOption("-Dprism.verbose=true");
var env = Bridge.CreateJVM(setup);
java.lang.System.@out.println("Greetings from C# to Java world!");
Console.WriteLine("Initializing...");
var klass = env.FindClass("modena/Modena");
Console.WriteLine("Finding main()...");
var mainMethodId = klass.getMethods().First(m => m.getName().Equals("main")).GetMethodId();
Console.WriteLine("Calling main()...");
env.CallStaticVoidMethod(klass, mainMethodId, Convertor.ParArrayStrongC2JString(env, new string[0]));
Console.WriteLine("Ended, press enter");
Console.ReadLine();
}
protected static void InitializeOpenGL()
{
Win32.oevSetDriverVersion("10.18.10.3621", 2176);
Win32.oevClientLoadDatabase(File.ReadAllText("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml"));
Win32.oevClientInitialize();
for (var i = 0; i <= 9; i++)
{
var tree = Marshal.PtrToStringAnsi(Win32.oevClientGetCapsAndExtTree(i));
Console.WriteLine(tree.Split('\n').First(ln => ln.Contains("text_id=\"357\"")));
}
// Optimus should be activated by now!
}
我还发现了在.NET下激活Optimus的真正原因......但很可能C / C ++的相同代码不起作用,因为它正是Java版本所做的(JNI调用)
PS:我刚刚确认“OpenTK”(OpenGL的.NET包装器)也无法激活Optimus。我完全糊涂了......