java

位置:IT落伍者 >> java >> 浏览文章

Java 3D的动画展示图(Part1-使用JMF)


发布日期:2022年06月24日
 
Java 3D的动画展示图(Part1-使用JMF)

在Java D场景中插入动画片段使D内容更加有趣充实一段动画可以在更令人信服的背景下展示例如飘动的云繁忙的城市街道或者是从窗向外看的效果动画可以在屏幕效果和游戏效果之间任意转换

这篇文章被分为两个部分描写我怎样实现一个Java D动画屏幕效果在这个部分我将说明我怎样利用JMF(Java Media Framework)特别是在JMF Performance Pack for Windows ve情况下我的另外两个工具是JSE 和Java D 我将讨论另外的使用Quicktime for Java的动画屏幕版本

是应用JMF MovieD在不同时间截取的两幅截屏右边截屏是从屏幕后看的效果

MovieD应用截屏

此应用程序中重点

JMF和Java D的集成屏幕以任意尺寸成倍增加在一个应用程序由于屏幕是JavaD的ShapeD类的一个子类因此它可以很容易的统一到各种Java D场景中

程序执行使用ModelViewController设计模式屏幕是一个视频元素由JMFMovieScreen类描述动画是一个由JMFSnapper类控制的模型部分一个Java D Behavior类TimeBehavior控制动画定时定期更新所有JMF编码都存放在JMFSnapper类可以很方便的测试各种变化这篇文章的第二部分JMFSnapper由QuickTime for Java版本中的QTSnapper取代

Java D 的使用将会使动画的播放速度毫无困难的上升到帧/秒

使用JMF出现问题的讨论问题是我首选解决方案将不会工作JMF有可能变为一个巨大的API但在其内部仍有一些程序没有及时运行

我坐在山上

事实上我正坐在一个冰冷的办公室我真正的意思是说这篇文章建立在大量Java D和JMF背景知识之上

我将不会细致地解释Java D的基础知识因为它们都可以在OReilly文章Killer Game Programming in Java(以下简称KGPJ)中找到例如场景效果图是其第章中的轻微改良CheckersD的版本实例我再生了这些编码以生成底版蓝天和灯光

假如你不想买这本书没关系所有篇章的初稿和所有编码都可以在此书的站点查阅

在此文章中我将会解释我用来从动画中抽取帧的JMF技术我将不会讨论流媒体或者编码转换

应用简述

动画由JMFSnapper类加载播放并且不断的循环播放直到被停止

JMFMovieScreen生成动画屏幕并在底版上控制Java D四边形

显示这些类的应用(该场景图说明场景中Java D节点怎样连接在一起)

MovieD场景图

种的很多细节可以被忽略此图KGPJ章中的得CheckersD实例有很多相似之处 只有特殊动画的节点是新的

由于节点关系JMFMovieScreen和TimeBehavior对象以三角形表示JMFSnapper对象不属于这张图但由JMFMovieScreen调用

毫秒TimeBehavior对象调用JMFMovieScreen类中的nextFrame()方法接下来调用JMFSnapper中的getFrame()方法获取动画中当前播放的帧由JMFMovieScreen控制成像

TimeBehavior是Java D的Behavior类的子类它是Java D应用的计时器它与KGPJ章中的D sprites实例中的TimeBehavior类十分相似

观察应用过程的另一种方式就是察看它的UML类图表给出类中的公共方法被显示

MovieD类图表

MovieD的子类JFrameWrapMovieD是JPanel的一个子类展示了WrapMovieD如何构建场景图和将其译成应用的JPanel他使用CheckerFloor 和ColouredTiles类构建底版

JMFMovieScreen创建动画屏幕将其加入场景中通过创建一个JMFSnapper对象开始动画TimeBehavior每毫秒调用JMFMovieScreen中的nextFrame()方法 nextFrame()调用JMFSnapper中的getFrame()得到当前帧

这个例子中的所有编码此文章的早期版本可以在KGPJ网点查询

准备动画

动画它的屏幕和更新屏幕的TimeBehavior对象都是由WrapMovieD中的addMovieScreen()方法创立

// globalsprivate BranchGroup sceneBG;private JMFMovieScreen ms;

// the movie screenprivate TimeBehavior timer;

// to update screenprivate void addMovieScreen(String fnm){// put the movie in fnm onto a movie screenms = new JMFMovieScreen( new Pointf(f ) f fnm);

sceneBGaddChild(ms);

// set up the timer for animating the movietimer = new TimeBehavior( ms);

// update movie every ms (== frames/sec)timersetSchedulingBounds(bounds);

sceneBGaddChild(timer);}

两个Java D addChild()方法调用JMFMovieScreen和TimeBehavior节点间的连接setSchedulingBounds()激活TimeBehavior节点

创建动画屏幕

JMFMovieScreen是Java D的ShapeD类的一个子类所以必须仔细说明它的外形的几何形状和外观

几何形状是指动画图像的四个边尺寸上成比例它的最大尺寸(高 宽)必须向构造器仔细说明这个四方形是垂直的朝向Z轴正方向可以在底版的任何位置被定位

四方形外观是双面允许从前或后观看动画结构是用双线性插值可以降低动画图像的像素化

大多数的功能是从KGPJ章中的FPS(firstperson shooter)实例中的ImageCsSeries类拷贝而来 ImageCsSeries在一个区域中显示一系列的GIF图片 为了简短起见我仅描述了JMFMovieScreen与ImageCsSeries的不同特征

高效显示图像

动画中的一个帧被转换结构扩大四倍分为两个步骤第一步 提供的BufferedImage传给Java D的ImageComponentD对象然后传给Java D TextureD

区域的图像更新非常快每秒更新要求结构更新因此结构有效率的更新非常的重要这种高效率在利用BufferedImage和ImageComponentD对象进行格式化的情况下是可能的

JMFMovieScreen使用的ImageComponentD对象以以下方式声明

ImageComponentD ic = new ImageComponentD(ImageComponentDFORMAT_RGBFORMAT_SIZE FORMAT_SIZE true true);

构造器剩余两个需要说明的讨论点是它使用by referenceYup模式这些模式降低了存储结构图像的内存大小因为Java D避免将图像从应用空间拷贝到图形内存

在Windows OS环境下使用OpenGL作为Java D优先图像引擎ImageComponentD格式应是ImageComponentDFORMAT_RGBBufferedImage格式应是BufferedImageTYPE_BYTE_BGRBufferedImage格式在JMFSnapper中确定

此项技术的更多细节可以在中查询

将纹理加进区域

通常在一个区域中确定一幅图像的方法是将图像的坐下角连接到区域的左下角然后逆时针连接剩余的几个角说明这种方法

图像与区域之间的标准连接

图像坐标区间在X Y轴的 之间Y轴正方向例如图像左下点坐标为(右上点为(

Yup模式使用图像坐标Y轴翻转负方向意味着()代表图像左上点)指向右下

Yup模式建立图像坐标必须分配给区域中不同点以便获得图像的相同定位显示了最新配置

Yup模式使用时图像与区域之间的连接

连接区域点与图像定位的JMFMovieScreen编码是

TexCoordf q = new TexCoordf();

qset(f f);

planesetTextureCoordinate( q);

// () tex coord > top left quad point (p)qset(f f);

planesetTextureCoordinate( q);

// () > top right (p)qset(f f);

planesetTextureCoordinate( q);

// () > bottom right (p)qset(f f);

planesetTextureCoordinate( q);

// () > bottom left (p)

PLANE对象指代区域

更新图像

以上所讲TimeBehavior是被设置用来被毫秒调用JMFMovieScreen的nextFrame()方法nextFrame()调用JMFSnapper对象中的getFrame()方法获得被看作BufferedImage对象的当前动画帧指派给一个mageComponentD对象然后传给区域图像nextFrame()是

// globalsprivate TextureD texture;

// used by the quadprivate ImageComponentD ic;

private JMFSnapper snapper;

// to take snaps of the movieprivate boolean isStopped = false;

// is the movie stopped?public void nextFrame(){ if (isStopped) // movie has been stoppedreturn; BufferedImage im = snappergetFrame();

// get current frameif (im != null) {

上一篇:Java Web Start 入门(一)

下一篇:浅谈Java串行端口技术协议