使用Java 3D在背景上覆盖半透明层
我正在使用Java3D来可视化一个包含一些基本元素的房间。我有一个图像背景,我用使用Java 3D在背景上覆盖半透明层,java,java-3d,Java,Java 3d,我正在使用Java3D来可视化一个包含一些基本元素的房间。我有一个图像背景,我用background.setImageScaleMode(background.SCALE\u REPEAT)平铺它,使它填充整个帧。现在,我想在这个背景上添加另一个半透明背景,我想用SCALE\u FIT\u ALL将它拉伸到屏幕上。这将创建一个我无法实现的图像效果。然而,当我尝试这样做时,Java 3D抱怨说Group.addChild:child已经有了父级 不使用背景做同样事情的其他方法(例如,在2D原语上绘
background.setImageScaleMode(background.SCALE\u REPEAT)平铺它,使它填充整个帧代码>。现在,我想在这个背景上添加另一个半透明背景,我想用SCALE\u FIT\u ALL
将它拉伸到屏幕上。这将创建一个我无法实现的图像效果。然而,当我尝试这样做时,Java 3D抱怨说Group.addChild:child已经有了父级
不使用背景做同样事情的其他方法(例如,在2D原语上绘制)也很有趣
所以我的问题是,如何使用Java3D实现我想要的
MWE:图像可用。我想画背景为的bg-stars.png。缩放重复,然后在背景为的bg-glow.png上缩放。缩放适合所有的,可能不是你真正想要的,但是太长了,无法发表评论:
我做了一个添加多个背景的测试,它基本上“起作用”(也就是说:它没有导致错误消息)。但是Background
的文档说
如果多个背景节点处于活动状态,则将使用距离眼睛“最近”的背景节点
因此,我假设根本不可能同时显示多个背景
根据您想要实现的目标,可能有几种可能性。以下是一种可能“接近”您想要的方法。但我对Java3D的背景并不熟悉,我认为有更优雅、高效、灵活(或者简单地说:更好)的方法(比如用叠加纹理创建一个巨大的半透明四边形等等)
然而,这里的想法是将背景创建为单个图像。编写BuffereImage相当简单,并提供了很多可能性。因此,我拍摄了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;
}
}
import java.applet.applet;
导入java.awt.BorderLayout;
导入java.awt.Frame;
导入java.awt.Graphics2D;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入javax.imageio.imageio;
导入javax.media.j3d.Background;
导入javax.media.j3d.BoundingSphere;
导入javax.media.j3d.BranchGroup;
导入javax.media.j3d.Canvas3D;
导入javax.media.j3d.ImageComponent2D;
导入javax.media.j3d.Transform3D;
导入javax.media.j3d.TransformGroup;
导入com.sun.j3d.utils.applet.MainFrame;
导入com.sun.j3d.utils.geometry.ColorCube;
导入com.sun.j3d.utils.image.TextureLoader;
导入com.sun.j3d.utils.universe.SimpleUniverse;
公共类SimpleBackgroundTest扩展小程序
{
专用静态最终整数宽度=1200;
专用静态最终内部高度=1200;
公共静态void main(字符串[]args)引发IOException
{
System.setProperty(“sun.awt.noerasebackground”、“true”);
框架=新主机(新SimpleBackgroundTest(),宽度,高度);
}
公共SimpleBackgroundTest()
{
setLayout(新的BorderLayout());
Canvas3D c=新的Canvas3D(SimpleUniverse.getPreferredConfiguration());
添加(“中心”,c);
BranchGroup=新建BranchGroup();
addChild(createSomeCube());
BuffereImage stars=null;
BuffereImage发光=空;
尝试
{
stars=ImageIO.read(新文件(“bg stars.png”);
glow=ImageIO.read(新文件(“bg glow.png”);
}
捕获(IOE异常)
{
e、 printStackTrace();
}
BuffereImage平铺=创建平铺(星形、宽度、高度);
BuffereImage overlay=createOverlay(平铺、发光);
背景背景=创建背景(覆盖);
addChild组(背景);
简单宇宙=新的简单宇宙(c);
宇宙添加分支图(组);
universe.getViewingPlatform().setNominalViewingTransform();
}
私有静态缓冲区图像创建平铺(
BuffereImage图像,int-targetSizeX,int-targetSizeY)
{
BuffereImage结果=新的BuffereImage(
targetSizeX,targetSizeY,
BuffereImage.TYPE_INT_ARGB);
Graphics2D g=result.createGraphics();
对于(int x=0;x