电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Java 3D的動畫展示(Part1-使用JMF)

瀏覽:136日期:2024-06-12 13:15:54
內容: Java 3D的動畫展示(Part1-使用JMF)翻譯:Andrew Davison, Killer Game Programming in Java的作者06/01/2005 翻譯 Caesh版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明英文原文地址:http://www.onjava.com/pub/a/onjava/2005/06/01/kgpjava.html中文地址:http://www.matrix.org.cn/resource/article/43/43675_Java_3D.html關鍵詞: Java 3D JMF在Java 3D場景中插入動畫片段使3D內容更加有趣充實.一段動畫可以在更令人信服的背景下展示,例如飄動的云,繁忙的城市街道,或者是從窗向外看的效果.動畫可以在屏幕效果和游戲效果之間任意轉換.這篇文章被分為兩個部分,描寫我怎樣實現一個Java 3D動畫屏幕效果.在這個部分,我將說明我怎樣利用JMF(Java Media Framework),特別是在JMF Performance Pack for Windows v.2.1.1e情況下.我的另外兩個工具是J2SE 5.0和Java 3D 1.3.2.我將討論另外的使用Quicktime for Java的動畫屏幕版本.圖1是應用JMF Movie3D在不同時間截取的兩幅截屏,右邊截屏是從屏幕后看的效果. 圖1. Movie3D應用截屏此應用程序中重點:。JMF和Java 3D的集成.屏幕以任意尺寸成倍增加在一個應用程序.由于屏幕是Java3D的Shape3D類的一個子類,因此它可以很容易的統一到各種Java 3D場景中.。程序執行使用Model-View-Controller設計模式.屏幕是一個視頻元素,由JMFMovieScreen類描述.動畫是一個由JMFSnapper類控制的模型部分.一個Java 3D Behavior類,TimeBehavior,控制動畫定時定期更新.所有JMF編碼都存放在JMFSnapper類,可以很方便的測試各種變化.這篇文章的第二部分JMFSnapper由QuickTime for Java版本中的QTSnapper取代.。Java 3D 的使用將會使動畫的播放速度毫無困難的上升到25幀/秒.。使用JMF出現問題的討論.問題是我首選解決方案將不會工作-JMF有可能變為一個巨大的API,但在其內部仍有一些程序沒有及時運行.1. 我坐在山上事實上,我正坐在一個冰冷的辦公室.我真正的意思是說這篇文章建立在大量Java 3D和JMF背景知識之上.我將不會細致地解釋Java 3D的基礎知識,因為它們都可以在O'Reilly文章Killer Game Programming in Java(以下簡稱KGPJ)中找到.例如,圖1場景效果圖是其第15章中的輕微改良Checkers3D的版本實例.我再生了這些編碼以生成底版,藍天和燈光.假如你不想買這本書,沒關系,所有篇章的初稿和所有編碼都可以在此書的站點查閱.在此文章中,我將會解釋我用來從動畫中抽取幀的JMF技術.我將不會討論流媒體或者編碼轉換.2. 應用簡述動畫由JMFSnapper類加載播放,并且不斷的循環播放直到被停止.JMFMovieScreen生成動畫屏幕,并在底版上控制Java 3D四邊形.圖2顯示這些類的應用(該場景圖說明場景中Java 3D節點怎樣連接在一起) 圖2:Movie3D場景圖圖2種的很多細節可以被忽略,此圖KGPJ15章中的得Checkers3D實例有很多相似之處. 只有特殊動畫的節點是新的.由于節點關系,JMFMovieScreen和TimeBehavior對象以三角形表示.JMFSnapper對象不屬于這張圖,但由JMFMovieScreen調用.每40毫秒,TimeBehavior對象調用JMFMovieScreen類中的nextFrame()方法.接下來調用JMFSnapper中的getFrame()方法獲取動畫中當前播放的幀,由JMFMovieScreen控制成像.TimeBehavior是Java 3D的Behavior類的子類,它是Java 3D應用的計時器.它與KGPJ18章中的3D sprites實例中的TimeBehavior類十分相似.觀察應用過程的另一種方式就是察看它的UML類圖表,圖3給出。類中的公共方法被顯示.圖3:Movie3D類圖表Movie3D的子類JFrame,WrapMovie3D是JPanel的一個子類.圖2展示了WrapMovie3D如何構建場景圖,和將其譯成應用的JPanel.他使用CheckerFloor 和ColouredTiles類構建底版.JMFMovieScreen創建動畫屏幕,將其加入場景中,通過創建一個JMFSnapper對象開始動畫.TimeBehavior每40毫秒調用JMFMovieScreen中的nextFrame()方法. nextFrame()調用JMFSnapper中的getFrame()得到當前幀. 這個例子中的所有編碼,此文章的早期版本可以在KGPJ網點查詢.3. 準備動畫動畫,它的屏幕和更新屏幕的TimeBehavior對象,都是由WrapMovie3D中的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 screen ms = new JMFMovieScreen( new Point3f(1.5f, 0, -1), 2.0f, fnm); sceneBG.addChild(ms); // set up the timer for animating the movie timer = new TimeBehavior(40, ms); // update movie every 40ms (== 25 frames/sec) timer.setSchedulingBounds(bounds); sceneBG.addChild(timer);} 兩個Java 3D addChild()方法調用JMFMovieScreen和TimeBehavior節點間的連接.setSchedulingBounds()激活TimeBehavior節點.4. 創建動畫屏幕JMFMovieScreen是Java 3D的Shape3D類的一個子類.所以必須仔細說明它的外形的幾何形狀和外觀.幾何形狀是指動畫圖像的四個邊尺寸上成比例,它的最大尺寸(高 寬)必須向構造器仔細說明.這個四方形是垂直的,朝向Z軸正方向,可以在底版的任何位置被定位.四方形外觀是雙面,允許從前或后觀看動畫.結構是用雙線性插值,可以降低動畫圖像的像素化.大多數的功能是從KGPJ24章中的FPS(first-person shooter)實例中的ImageCsSeries類拷貝而來. ImageCsSeries在一個區域中顯示一系列的GIF圖片. 為了簡短起見,我僅描述了JMFMovieScreen與ImageCsSeries的不同特征.高效顯示圖像動畫中的一個幀被轉換結構擴大四倍;分為兩個步驟:第一步 提供的BufferedImage傳給Java 3D的ImageComponent2D對象,然后傳給Java 3D Texture2D.區域的圖像更新非常快:每秒更新25幀,要求結構更新25次.因此結構有效率的更新非常的重要.這種高效率在利用BufferedImage和ImageComponent2D對象進行格式化的情況下是可能的.JMFMovieScreen使用的ImageComponent2D對象以以下方式聲明:ImageComponent2D ic = new ImageComponent2D( ImageComponent2D.FORMAT_RGB, FORMAT_SIZE, FORMAT_SIZE, true, true);構造器剩余兩個需要說明的討論點是它使用'by reference'和'Y-up'模式.這些模式降低了存儲結構圖像的內存大小,因為Java 3D避免將圖像從應用空間拷貝到圖形內存. 在Windows OS環境下,使用OpenGL作為Java 3D優先圖像引擎,ImageComponent2D格式應是ImageComponent2D.FORMAT_RGB,BufferedImage格式應是BufferedImage.TYPE_3BYTE_BGR.BufferedImage格式在JMFSnapper中確定.此項技術的更多細節可以在j3d.org中查詢.將紋理加進區域通常在一個區域中確定一幅圖像的方法是將圖像的坐下角連接到區域的左下角,然后逆時針連接剩余的幾個角.圖4說明這種方法. 圖4.圖像與區域之間的標準連接圖像坐標區間在X Y軸的0 1之間,Y軸正方向.例如,圖像左下點坐標為(0,0),右上點為(1,1).當'Y-up'模式使用,圖像坐標Y軸翻轉,負方向.意味著(0,0)代表圖像左上點,(1,1)指向右下.當'Y-up'模式建立,圖像坐標必須分配給區域中不同點以便獲得圖像的相同定位.圖5顯示了最新配置. 圖5.'Y-up'模式使用時,圖像與區域之間的連接連接區域點與圖像定位的JMFMovieScreen編碼是TexCoord2f q = new TexCoord2f();q.set(0.0f, 0.0f); plane.setTextureCoordinate(0, 3, q); // (0,0) tex coord top left quad point (p3)q.set(1.0f, 0.0f); plane.setTextureCoordinate(0, 2, q); // (1,0) top right (p2)q.set(1.0f, 1.0f); plane.setTextureCoordinate(0, 1, q); // (1,1) bottom right (p1)q.set(0.0f, 1.0f); plane.setTextureCoordinate(0, 0, q); // (0,1) bottom left (p0)PLANE對象指代區域.更新圖像以上所講,TimeBehavior是被設置用來被40毫秒調用JMFMovieScreen的nextFrame()方法.nextFrame()調用JMFSnapper對象中的getFrame()方法獲得被看作BufferedImage對象的當前動畫幀.指派給一個mageComponent2D對象,然后傳給區域圖像.nextFrame()是:// globalsprivate Texture2D texture; // used by the quadprivate ImageComponent2D 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 stopped return; BufferedImage im = snapper.getFrame();// get current frame if (im != null) { ic.set(im); //assign frame to ImageComponent2D texture.setImage(0,ic); // make it the shape's texture } else System.out.println('Null BufferedImage');}snapper,JMFSnapper對象,由JMFMovieScreen的構造器創建:// load and play the moviesnapper = new JMFSnapper(movieFnm);JMFSnapper的簡單接口掩蓋了播放動畫和從動畫中抽取幀的JMF編碼的復雜.著這個系列的第二部分,JMFSnapper由使用QuickTime for Java的版本取代,對JMFMovieScreen只需要作出微小改動.5. 管理動畫JMF提供了一種訪問動畫幀的高水平方法.以下的編碼片斷闡明了主要元素.我將省去錯誤檢驗和異常處理.// create a movie player, in a 'realized' stateURL url = new URL('file:' + movieFnm);Player p = Manager.createRealizedPlayer(url);// create a frame positionerFramePositioningControl fpc = (FramePositioningControl) p.getControl('javax.media.control. FramePositioningControl');// create a frame grabberFrameGrabbingControl fg = (FrameGrabbingControl) p.getControl('javax.media.control. FrameGrabbingControl');// request that the player changes to a 'prefetched' statep.prefetch();// wait until the player is in that state...// move to a particular frame, e.g. frame 100fpc.seek(100); // take a snap of the current frameBuffer buf = fg.grabFrame(); // get its video format detailsVideoFormat vf = (VideoFormat) buf.getFormat();// initialize BufferToImage with video formatBufferToImage bufferToImage = new BufferToImage(vf);// convert the buffer to an imageImage im = bufferToImage.createImage(buf);// specify the format of desired BufferedImageBufferedImage formatImg = new BufferedImage( FORMAT_SIZE, FORMAT_SIZE, BufferedImage.TYPE_3BYTE_BGR);// convert the image to a BufferedImageGraphics g = formatImg.getGraphics();g.drawImage(im, 0, 0, FORMAT_SIZE, FORMAT_SIZE, null);g.dispose();一個媒體播放器從制作到完成需要六個步驟.播放器在構思過程中要清楚怎樣運行數據,可以在要求時提供視覺上的組成和控制器.我要求兩個控制器:FramePositioningControl和FrameGrabbingControl. FramePositioningControl提供了seek()和skip()方法,可以在動畫中查檢特殊幀.FrameGrabbingControl提供grabFrame()方法,可以在動畫的視頻軌跡中抽取當前幀.為了使這些控制器工作,播放器必須由構思過程進入構建過程.播放器開始準備播放媒體,媒體數據被加載.prefetch()的調用是異步的,意味著編碼必須等待直到轉換過程結束.標準JMF譯碼解決方案使用waitForState()方法,此方法將使執行過程暫停直到一個狀態轉換事件將其喚醒.如果想尋找一個幀,可以使用seek()方法在軌跡中將這個幀定位,然后利用grabFrame()方法提取.提取的Buffer對象轉變為JMFMovieScreen要求的 BufferedImage對象必須經過幾個轉變過程.注意:BufferedImage對象是TYPE_3BYTE_BGR格式.Sun公司的JMF website有很多很有用的小例子,其中之一,Seek.java展示了如何使用FramePositioningControl方法做成動畫.三步審查不幸的是,編碼大體上是錯誤的,至少在JMF Performance Pack for Windows v.2.1.1e.我審查了幾個編碼重寫以獲得可工作的JMFSnapper版本.1. 兩個控制器,FramePositioningControl和FrameGrabbingControl,在JMF下的缺省播放器模塊中是很難獲得的.'本地模塊'播放器被要求:Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));這個播放器組成龐大,對Swing GUIs例如JFrame和JPanel會產生弱化的影響.然而,我不需要展示這個播放器.使用本地模塊播放器會產生一系列嚴重的后果,媒體加載時間過長,無序播放.2.在一番沉思后,我確定了加速播放器的最佳方法是減少其工作量.我將音頻從MPEG文件剝離,確保文件以簡單的MPEG-1格式儲存.一些視頻編輯工具可以完成這些工作.我使用的是兩個免費的工具:MPEG Properties和FlasKMPEG.被剝離的動畫播放很順暢,幀率是一個常數,沒有幀遺漏.不過,FramePositioningControl類是不可靠的.在我的WinXP機器,seek()方法幾乎總是失敗,skip()方法五次也只能成功一次.3.我下定決心舍棄FramePositioningControl.我的幀抓取運算法則依賴每隔一段時間調用FrameGrabbingControl的grabFrame()方法當播放器播放動畫.我已有可以很可靠的從只有視頻的MPEG-1文件中抓取幀的編碼.它也可以從視頻音頻齊全的文件中還算不錯的抓取幀,但是播放器啟動會很慢.而且,無序播放會引起幀的不規律抓取.我在JMFSnapper前段加寫了“等待編碼以處理視頻-音頻文件.JMFSnapper對象等待播放器啟動和第一個動畫幀變的可用.等待第一幀JMFSnapper構造器調用waitForBufferToImage()方法以便重復的調用hasBufferToImage()直到它檢測到第一個視頻幀.hasBufferToImage()調用FrameGrabbingControl的grabFrame(),檢測返回的Buffer對象是否含有視頻信息數據.它使用這些數據初始化一個BufferToImage對象,此對象被用來將每一個抓取幀轉化為圖像.// globalsprivate FrameGrabbingControl fg; // frame grabberprivate BufferToImage bufferToImage = null;private int width, height; // frame dimensionsprivate boolean hasBufferToImage(){ Buffer buf = fg.grabFrame(); // take a snap if (buf == null) { System.out.println('No grabbed frame'); return false; } // there is a buffer, but check if it's empty VideoFormat vf = (VideoFormat) buf.getFormat(); if (vf == null) { System.out.println('No video format'); return false; } System.out.println('Video format: ' + vf); // extract the image's dimensions width = vf.getSize().width; height = vf.getSize().height; // initialize bufferToImage with video format bufferToImage = new BufferToImage(vf); return true;}這個編碼方法的一個微小缺點是第一個視頻幀(引起hasBufferToImage()返回true)在BufferToImage對象初始化后被丟棄.作為BufferedImage to JMFMovieScreen這個幀不能被使用.抓圖JMFSnapper中的最重要的公共方法是getFrame(),此方法被周期性的調用以獲得播放動畫中的當前幀.// globalprivate BufferedImage formatImg; // frame imagesynchronized public BufferedImage getFrame(){ // grab the current frame as a buffer object Buffer buf = fg.grabFrame(); if (buf == null) { System.out.println('No grabbed buffer'); return null; } // convert buffer to image Image im = bufferToImage.createImage(buf); if (im == null) { System.out.println('No grabbed image'); return null; } // convert the image to a BufferedImage Graphics g = formatImg.getGraphics(); g.drawImage(im, 0, 0, FORMAT_SIZE, FORMAT_SIZE, null); // Overlay current time on top of the image g.setColor(Color.RED); g.setFont(new Font('Helvetica',Font.BOLD,12)); g.drawString(timeNow(), 5, 14); g.dispose(); return formatImg;} // end of getFrame() getFrame()和closeMovie()方法在JMFSnapper中是同步的.closeMovie()中止播放器,在任何時間都可能被調用.同步關鍵字確保當幀從動畫中被抽取時播放器不會被關閉. formatImg BufferedImage對象在JMFSnapper構造器中初始化:formatImg = new BufferedImage( FORMAT_SIZE, FORMAT_SIZE, BufferedImage.TYPE_3BYTE_BGR);6. 另一種抓圖方案 Sun公司的JMF實例網點提供了另外兩種抽取幀方法.VideoRendererDemoJMFJ3D實例由Java 3D和JMF應用程序組成,它展示了怎樣將一個視頻環繞一個主體.Java 3D與我討論的一些東西-使用 BufferedImage.TYPE_3BYTE_BGR格式的BufferedImage傳遞給ImageComponent2D對象,然后變為柱面圖像-在本質上是相同的.這個圖像也使用BufferedImage.TYPE_4BYTE_ABGR格式,此格式是Solaris要求的以便符合提及的圖像格式.這個程序的JMF與我們的相當不同.一個JMF的VideoRenderer應用程序接口是附加在TrackControl對象,此對象是控制動畫的視頻軌跡.一旦TrackControl對象被喚醒,VideoRenderer的process()方法被自動調用以便適用視頻中的每一個幀.process()的輸入是Buffer對象.勝于我曾描述的Buffer-to-BufferedImage轉換步驟,DemoJMFJ3D以低水準構建BufferedImage,BufferedImage的像素化圖像和Buffer原始數據時間的比特數組拷貝.3D聊天室實例中的DemoJMFJ3D編碼盡在Java Media APIs: Cross-Platform Imaging, Media and Visualization,A. Terrazas, J. Ostuni和M. Barlow所著.這本書是對于JMF是本很好的入門書籍,其中也有很多關于Java 3D的有趣篇章.Processor Codec插件FrameAccess實例使用很多更先進的JMF元素,以Processor codec插件為中心.Processor類是Player的一個延伸版本,它對于媒體數據處理有更強的能力.一個多媒體數字信號編解碼器插件能夠從一段軌跡中讀取幀,以任意方式處理它們,然后將他們寫回軌跡.Codec的process()方法中,提供其一個含有輸入幀的Buffer對象,空Buffer對象輸出.FrameAccess附加一個Codec插件以訪問動畫的視頻軌跡,使用輸入幀Buffer對象傳遞給process()方法以產生一些關于視頻的基本統計表.這個實例易于改進以便將Buffer對象轉化為BufferedImage,任意使用我的方法或者DemoJMFJ3D的比特數組技術.不幸的是,Processor類不能用來支持插件;結果,插件在JMF 1.0或2.0-based版本下不能工作.在使用Sun公司的JMF實例前尋找jmf-interest mailing list是一個不錯的注意,因為大多數的程序在各種版本的JMF下都存在問題. Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標簽: Java
相關文章:
主站蜘蛛池模板: 海鲜池-专注海鲜鱼缸、移动海鲜缸、饭店鱼缸设计定做-日晟水族厂家 | 北京模型公司-军事模型-工业模型制作-北京百艺模型沙盘公司 | 密封无忧网 _ 专业的密封产品行业信息网 | 冻干机(冷冻干燥机)_小型|实验型|食品真空冷冻干燥机-松源 | 国产离子色谱仪,红外分光测油仪,自动烟尘烟气测试仪-青岛埃仑通用科技有限公司 | 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | 上海办公室设计_办公楼,写字楼装修_办公室装修公司-匠御设计 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 科箭WMS仓库管理软件-TMS物流管理系统-科箭SaaS云服务 | 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 小型铜米机-干式铜米机-杂线全自动铜米机-河南鑫世昌机械制造有限公司 | 砂磨机_立式纳米砂磨机_实验室砂磨机-广州儒佳化工设备厂家 | CCE素质教育博览会 | CCE素博会 | 教育展 | 美育展 | 科教展 | 素质教育展 | 胶水,胶粘剂,AB胶,环氧胶,UV胶水,高温胶,快干胶,密封胶,结构胶,电子胶,厌氧胶,高温胶水,电子胶水-东莞聚力-聚厉胶粘 | 天津热油泵_管道泵_天津高温热油泵-天津市金丰泰机械泵业有限公司【官方网站】 | 红酒招商加盟-葡萄酒加盟-进口红酒代理-青岛枞木酒业有限公司 | 辽宁资质代办_辽宁建筑资质办理_辽宁建筑资质延期升级_辽宁中杭资质代办 | 注塑模具_塑料模具_塑胶模具_范仕达【官网】_东莞模具设计与制造加工厂家 | 便民信息网_家电维修,家电清洗,开锁换锁,本地家政公司 | 水轮机密封网 | 水轮机密封产品研发生产厂家 | 奶茶加盟,奶茶加盟店连锁品牌-甜啦啦官网 | 山东齐鲁漆业有限公司【官网】-工业漆专业生产厂家 | 包装设计公司,产品包装设计|包装制作,包装盒定制厂家-汇包装【官方网站】 | 合肥注册公司|合肥代办营业执照、2024注册公司流程 | 苏州伊诺尔拆除公司_专业酒店厂房拆除_商场学校拆除_办公楼房屋拆除_家工装拆除拆旧 | 伟秀电气有限公司-10kv高低压开关柜-高低压配电柜-中置柜-充气柜-欧式箱变-高压真空断路器厂家 | 拉力测试机|材料拉伸试验机|电子拉力机价格|万能试验机厂家|苏州皖仪实验仪器有限公司 | 农产品溯源系统_农产品质量安全追溯系统_溯源系统 | 电镀整流器_微弧氧化电源_高频电解电源_微弧氧化设备厂家_深圳开瑞节能 | 混合气体腐蚀试验箱_盐雾/硫化氢/气体腐蚀试验箱厂家-北京中科博达 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 扬州汇丰仪表有限公司| 无缝方管|无缝矩形管|无缝方矩管|无锡方管厂家 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 氧化铁红厂家-淄博宗昂化工| 破碎机锤头_耐磨锤头_合金锤头-鼎成机械一站式耐磨铸件定制服务 微型驱动系统解决方案-深圳市兆威机电股份有限公司 | 高压分散机(高压细胞破碎仪)百科-北京天恩瀚拓 | 台式低速离心机-脱泡离心机-菌种摇床-常州市万丰仪器制造有限公司 | 北京亦庄厂房出租_经开区产业园招商信息平台| 列管冷凝器,刮板蒸发器,外盘管反应釜厂家-无锡曼旺化工设备有限公司 | 农产品溯源系统_农产品质量安全追溯系统_溯源系统 |