0

我有一个 Java/Swing/Java3D/JOGAMP JOGL/ 应用程序,其中一组 XYZ 滑块控制 3D 查看器位置。它在 MacOS (10.11) 上运行良好。但是,在 Windows 10(64 位)下运行时,屏幕的 3DCanvas 区域有时会被空白灰色覆盖。

我为 Canvas3D 使用黑色背景,并使用默认的双缓冲。

有人建议使用极简应用程序进行测试,我从 Java3D.org 复制了使用“PyramidEample.java”代码示例的相同问题(发布在下面)

这是我在 Windows-10(64 位)中看到的:

1) 将应用程序图标化到 Dock,然后重新调整窗口(去图标化)时会出现该错误。当应用程序窗口膨胀时,您会在几分之一秒内看到 Canvas3D 区域中的正确图像,然后将其覆盖或替换为纯灰色(与滑块控件的背景颜色相同)。

如果我拖动滑块,Canvas3D 将继续显示 3D 内容。在 Swing 鼠标处理程序处理其中一个应用程序滑块后,我从未见过灰色封面。

2)当我将应用程序窗口横向拖出屏幕,然后将其反转并向后拖动时,Canvas3D 部分在正常图像和纯灰色之间闪烁。在拖动结束时(应用程序完全封闭在屏幕中),最终的 Canvas3D 区域是不可预测的......它可以在窗口栏的鼠标释放上绘制为普通灰色与纯灰色。

3) 睡眠-非睡眠。如果我将我的应用程序放在前台并让 Win 笔记本电脑休眠,当我将其唤醒时,我的应用程序会在 Canvas3D 应该绘制的位置显示纯灰色。 演示错误外观的视频剪辑

我试过的:

1)双缓冲问题?我尝试将 Canvas3D 设置为禁用双缓冲,但没有效果。

2) 我将代码放在应用程序的 WindowListener 的“windowDeiconified(event)”方法中,该方法强制 Canvas3D 重新绘制,但什么也没做。

3) 由于这个错误是平台相关的,我尝试了所有可能的“系统外观”选项,但这并没有解决问题。

由于一个非常简单的测试应用程序会出现 3D 图形错误,如果您可以将其缩小到 Java3D 运行时环境变量,这将有所帮助: 1) 如果使用较旧的 Oracle Java3D(JRE 1.8.0_22 或更早版本)运行,而不是JOGAMP 1.6.0 替换堆栈,你看到视频中显示的错误了吗?
2) 无论您在什么 Java3D 堆栈上运行,了解您是否可以看到此错误都会很有帮助。

Java 编译器:1.8 Java JDK-JRE:1.8.0_102 Java 3D:JOGAMP:3D [dev] 1.6.0-pre12-daily-experimental daily 操作系统:Windows 10 Pro(64 位) 测试计算机:带 NVIDIA 的戴尔笔记本电脑 E6500 Quadro NVS 160M 卡(驱动程序 9.18.13.4192)

import java.awt.Color;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.vecmath.*;

// An Egyptian pyramid
// Base divided into two triangles

public class PyramidExample {
   public static void main(String[] args) {
    SimpleUniverse universe = new SimpleUniverse();
    BranchGroup group = new BranchGroup();

    Point3f e = new Point3f(1.0f, 0.0f, 0.0f); // east
    Point3f s = new Point3f(0.0f, 0.0f, 1.0f); // south
    Point3f w = new Point3f(-1.0f, 0.0f, 0.0f); // west
    Point3f n = new Point3f(0.0f, 0.0f, -1.0f); // north
    Point3f t = new Point3f(0.0f, 0.721f, 0.0f); // top

    TriangleArray pyramidGeometry = new TriangleArray(18,
            TriangleArray.COORDINATES);
    pyramidGeometry.setCoordinate(0, e);
    pyramidGeometry.setCoordinate(1, t);
    pyramidGeometry.setCoordinate(2, s);

    pyramidGeometry.setCoordinate(3, s);
    pyramidGeometry.setCoordinate(4, t);
    pyramidGeometry.setCoordinate(5, w);

    pyramidGeometry.setCoordinate(6, w);
    pyramidGeometry.setCoordinate(7, t);
    pyramidGeometry.setCoordinate(8, n);

    pyramidGeometry.setCoordinate(9, n);
    pyramidGeometry.setCoordinate(10, t);
    pyramidGeometry.setCoordinate(11, e);

    pyramidGeometry.setCoordinate(12, e);
    pyramidGeometry.setCoordinate(13, s);
    pyramidGeometry.setCoordinate(14, w);

    pyramidGeometry.setCoordinate(15, w);
    pyramidGeometry.setCoordinate(16, n);
    pyramidGeometry.setCoordinate(17, e);
    GeometryInfo geometryInfo = new GeometryInfo(pyramidGeometry);
    NormalGenerator ng = new NormalGenerator();
    ng.generateNormals(geometryInfo);

    GeometryArray result = geometryInfo.getGeometryArray();

    // yellow appearance
    Appearance appearance = new Appearance();
    Color3f color = new Color3f(Color.yellow);
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
    Texture texture = new Texture2D();
    TextureAttributes texAttr = new TextureAttributes();
    texAttr.setTextureMode(TextureAttributes.MODULATE);
    texture.setBoundaryModeS(Texture.WRAP);
    texture.setBoundaryModeT(Texture.WRAP);
    texture.setBoundaryColor(new Color4f(0.0f, 1.0f, 0.0f, 0.0f));
    Material mat = new Material(color, black, color, white, 70f);
    appearance.setTextureAttributes(texAttr);
    appearance.setMaterial(mat);
    appearance.setTexture(texture);
    Shape3D shape = new Shape3D(result, appearance);
    group.addChild(shape);

    // above pyramid
    Vector3f viewTranslation = new Vector3f();
    viewTranslation.z = 3;
    viewTranslation.x = 0f;
    viewTranslation.y = .3f;
    Transform3D viewTransform = new Transform3D();
    viewTransform.setTranslation(viewTranslation);
    Transform3D rotation = new Transform3D();
    rotation.rotX(-Math.PI / 12.0d);
    rotation.mul(viewTransform);
    universe.getViewingPlatform().getViewPlatformTransform().setTransform(
            rotation);
    universe.getViewingPlatform().getViewPlatformTransform().getTransform(
            viewTransform);

    // lights
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
            1000.0);
    Color3f light1Color = new Color3f(.7f, .7f, .7f);
    Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
    DirectionalLight light1 = new DirectionalLight(light1Color,   
 light1Direction);
    light1.setInfluencingBounds(bounds);
    group.addChild(light1);
    Color3f ambientColor = new Color3f(.4f, .4f, .4f);
    AmbientLight ambientLightNode = new AmbientLight(ambientColor);
    ambientLightNode.setInfluencingBounds(bounds);
    group.addChild(ambientLightNode);

    universe.addBranchGraph(group);
  }
}
4

1 回答 1

0

对不起这个老重播。

将以下内容添加到您的主类中:

 static {
        // in JRE 7 from causing redraw problems (i.e. the Java 3D canvas is sometimes
        // drawn as a blank gray rectangle).      
        System.setProperty("sun.awt.noerasebackground", "true");    
    }

您的完整代码,这次使用 JFrame 和 Canvas 而不是默认的 SimpleUniverse 的内部框架:

package test;

import java.awt.*;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.universe.SimpleUniverse;
import javax.media.j3d.*;
import javax.swing.*;
import javax.vecmath.*;



// An Egyptian pyramid
// Base divided into two triangles

public class PyramidExample {

    static {
        // in JRE 7 from causing redraw problems (i.e. the Java 3D canvas is sometimes
        // drawn as a blank gray rectangle).      
        System.setProperty("sun.awt.noerasebackground", "true");    
    }

    /**
     * Main method
     * @param args
     */
   public static void main(String[] args) {
    JFrame frame = new JFrame("Pyramid Example");
    frame.setSize(800, 600);
    frame.setLayout(new BorderLayout());    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BorderLayout());
    frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
    mainPanel.setLayout(new BorderLayout());

    // get default configuration for 3D
    GraphicsConfiguration conf =   SimpleUniverse.getPreferredConfiguration();
    Canvas3D canvas = new Canvas3D(conf);
    // create simpleUniverse       
    SimpleUniverse universe = new SimpleUniverse(canvas);
    BranchGroup scene = createScene(universe);
    universe.addBranchGraph(scene);

    mainPanel.add(canvas, BorderLayout.CENTER);
    frame.setVisible(true);
   }

   /**
    * Create Scene graph
    * @param universe
    * @return
    */
  private static  BranchGroup createScene(SimpleUniverse universe) { 
    BranchGroup group = new BranchGroup();

    Point3f e = new Point3f(1.0f, 0.0f, 0.0f); // east
    Point3f s = new Point3f(0.0f, 0.0f, 1.0f); // south
    Point3f w = new Point3f(-1.0f, 0.0f, 0.0f); // west
    Point3f n = new Point3f(0.0f, 0.0f, -1.0f); // north
    Point3f t = new Point3f(0.0f, 0.721f, 0.0f); // top

    TriangleArray pyramidGeometry = new TriangleArray(18,
            TriangleArray.COORDINATES);
    pyramidGeometry.setCoordinate(0, e);
    pyramidGeometry.setCoordinate(1, t);
    pyramidGeometry.setCoordinate(2, s);

    pyramidGeometry.setCoordinate(3, s);
    pyramidGeometry.setCoordinate(4, t);
    pyramidGeometry.setCoordinate(5, w);

    pyramidGeometry.setCoordinate(6, w);
    pyramidGeometry.setCoordinate(7, t);
    pyramidGeometry.setCoordinate(8, n);

    pyramidGeometry.setCoordinate(9, n);
    pyramidGeometry.setCoordinate(10, t);
    pyramidGeometry.setCoordinate(11, e);

    pyramidGeometry.setCoordinate(12, e);
    pyramidGeometry.setCoordinate(13, s);
    pyramidGeometry.setCoordinate(14, w);

    pyramidGeometry.setCoordinate(15, w);
    pyramidGeometry.setCoordinate(16, n);
    pyramidGeometry.setCoordinate(17, e);
    GeometryInfo geometryInfo = new GeometryInfo(pyramidGeometry);
    NormalGenerator ng = new NormalGenerator();
    ng.generateNormals(geometryInfo);

    GeometryArray result = geometryInfo.getGeometryArray();

    // yellow appearance
    Appearance appearance = new Appearance();
    Color3f color = new Color3f(Color.yellow);
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
    Texture texture = new Texture2D();
    TextureAttributes texAttr = new TextureAttributes();
    texAttr.setTextureMode(TextureAttributes.MODULATE);
    texture.setBoundaryModeS(Texture.WRAP);
    texture.setBoundaryModeT(Texture.WRAP);
    texture.setBoundaryColor(new Color4f(0.0f, 1.0f, 0.0f, 0.0f));
    Material mat = new Material(color, black, color, white, 70f);
    appearance.setTextureAttributes(texAttr);
    appearance.setMaterial(mat);
    appearance.setTexture(texture);
    Shape3D shape = new Shape3D(result, appearance);
    group.addChild(shape);

    // above pyramid
    Vector3f viewTranslation = new Vector3f();
    viewTranslation.z = 3;
    viewTranslation.x = 0f;
    viewTranslation.y = .3f;
    Transform3D viewTransform = new Transform3D();
    viewTransform.setTranslation(viewTranslation);
    Transform3D rotation = new Transform3D();
    rotation.rotX(-Math.PI / 12.0d);
    rotation.mul(viewTransform);
    universe.getViewingPlatform().getViewPlatformTransform().setTransform(
            rotation);
    universe.getViewingPlatform().getViewPlatformTransform().getTransform(
            viewTransform);

    // lights
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
            1000.0);
    Color3f light1Color = new Color3f(.7f, .7f, .7f);
    Vector3f light1Direction = new Vector3f(4.0f, -7.0f, -12.0f);
    DirectionalLight light1 = new DirectionalLight(light1Color,   
 light1Direction);
    light1.setInfluencingBounds(bounds);
    group.addChild(light1);
    Color3f ambientColor = new Color3f(.4f, .4f, .4f);
    AmbientLight ambientLightNode = new AmbientLight(ambientColor);
    ambientLightNode.setInfluencingBounds(bounds);
    group.addChild(ambientLightNode);

    return group;
  }
}
于 2019-06-30T14:12:53.687 回答