gpt4 book ai didi

java - 使用 Java 3D 在背景上叠加半透明层

转载 作者:行者123 更新时间:2023-12-01 13:16:18 24 4
gpt4 key购买 nike

我正在使用 Java3D 来可视化一个包含一些基元的房间。我有一个图像背景,我使用 background.setImageScaleMode(Background.SCALE_REPEAT); 平铺,以便它填充整个框架。 。现在我想在此背景上添加另一个半透明背景,并且我想使用 SCALE_FIT_ALL 将其拉伸(stretch)以覆盖屏幕。 。这将创造出我无法以其他方式实现的图像效果。然而,当我尝试这样做时,Java 3D 提示 Group.addChild: child already has a parent .

不使用背景做同样事情的其他方法(例如在 2D 基元上绘制它)也会引起兴趣。

所以我的问题是如何使用 Java3D 实现我想要的目标?

MWE: 图片可用 here 。我想用 Background.SCALE_REPEAT 绘制 bg-stars.png然后在 bg-glow.png 上面加上 Background.SCALE_FIT_ALL .

最佳答案

可能不是您真正想要实现的目标,但评论太长:

我做了添加多个背景的测试,它基本上“有效”(也就是说:它没有导致错误消息)。但是 Background 的文档说

If multiple Background nodes are active, the Background node that is "closest" to the eye will be used.

因此,我认为根本不可能同时显示多个背景。

根据您想要实现的目标,可能有多种可能性。下面是一种可能“接近”您想要的方法。但我熟悉Java3D中的背景,并假设有更优雅、高效、灵活(或者简单地说:更好)的方法(比如创建一个巨大的、半-具有覆盖纹理或其他内容的透明四边形...)

但是,这里的想法是将背景创建为单个图像。编写 BufferedImages 相当简单,并且提供了很多可能性。因此,我采用 bg-stars.png 图像并创建该图像的“平铺”版本(足够大以填充特定区域 - 实际上,可以简单地使其与最大屏幕尺寸)。然后,我将其与“覆盖”图像 bg-glow.png 组合起来,只需将其绘制在平铺图像上即可。

生成的图像可用于创建背景。

乍一看,结果可能看起来像您想要实现的,但当然,可能有一些警告。例如。人们必须考虑如何实现这一点以适应窗口大小的变化。 (使用 ComponentListener 监听并更新图像很容易,但是......好吧)。

再说一遍:当然有更好的解决方案。但也许这至少可以作为一种解决方法,直到您找到更好的解决方案。

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;

import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class SimpleBackgroundTest extends Applet
{
private static final int WIDTH = 1200;
private static final int HEIGHT = 1200;

public static void main(String[] args) throws IOException
{
System.setProperty("sun.awt.noerasebackground", "true");
Frame frame = new MainFrame(new SimpleBackgroundTest(), WIDTH, HEIGHT);
}

public SimpleBackgroundTest()
{
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
add("Center", c);

BranchGroup group = new BranchGroup();
group.addChild(createSomeCube());

BufferedImage stars = null;
BufferedImage glow = null;
try
{
stars = ImageIO.read(new File("bg-stars.png"));
glow = ImageIO.read(new File("bg-glow.png"));
}
catch (IOException e)
{
e.printStackTrace();
}

BufferedImage tiled = createTiled(stars, WIDTH, HEIGHT);
BufferedImage overlay = createOverlay(tiled, glow);

Background background = createBackground(overlay);
group.addChild(background);

SimpleUniverse universe = new SimpleUniverse(c);
universe.addBranchGraph(group);
universe.getViewingPlatform().setNominalViewingTransform();
}

private static BufferedImage createTiled(
BufferedImage image, int targetSizeX, int targetSizeY)
{
BufferedImage result = new BufferedImage(
targetSizeX, targetSizeY,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
for (int x = 0; x < targetSizeX; x += image.getWidth())
{
for (int y = 0; y < targetSizeY; y += image.getHeight())
{
g.drawImage(image, x, y, null);
}
}
g.dispose();
return result;
}

private static BufferedImage createOverlay(
BufferedImage image, BufferedImage overlay)
{
BufferedImage result = new BufferedImage(
image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, image.getWidth(), image.getHeight(), null);
g.dispose();
return result;
}

private static Background createBackground(BufferedImage image)
{
TextureLoader textureLoader = new TextureLoader(image);
ImageComponent2D imageComponent = textureLoader.getImage();
Background background = new Background();
background.setImage(imageComponent);
background.setImageScaleMode(Background.SCALE_FIT_ALL);
background.setCapability(Background.ALLOW_IMAGE_WRITE);
background.setApplicationBounds(new BoundingSphere());
return background;
}

private TransformGroup createSomeCube()
{
ColorCube cube = new ColorCube(0.5f);
Transform3D t = new Transform3D();
t.rotY(0.2);
t.setScale(0.1);
TransformGroup tg = new TransformGroup();
tg.setTransform(t);
tg.removeAllChildren();
tg.addChild(cube);
return tg;
}
}

关于java - 使用 Java 3D 在背景上叠加半透明层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22440313/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com