国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

JAVA 3D世界的動(dòng)畫展示(Part2,使用QuickTime for Java)

瀏覽:74日期:2024-06-12 11:38:25
內(nèi)容: JAVA 3D世界的動(dòng)畫展示(Part2,使用QuickTime for Java)作者: Andrew Davison 翻譯 Caesh版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明英文原文地址:http://www.onjava.com/pub/a/onjava/2005/06/01/kgpjava_part2.html中文地址:http://www.matrix.org.cn/resource/article/43/43676_JAVA_3D.html關(guān)鍵詞: Java 3D QuickTime在這一系列的第一部分中,我描述了在JMF(JAVA媒體幀工作器 下同)的幫助下,怎樣將一部電影片斷插入JAVA 3D場景中。這個(gè)執(zhí)行過程使用Model-View-Controller設(shè)計(jì)模式。。動(dòng)畫屏幕是由JMFMovieScreen類表示的視覺元素。動(dòng)畫模型部分由JMFSnapper類控制。java 3D行為類,TimeBehavior,是動(dòng)畫中引起幀周期性恢復(fù)的控制類在這篇文章中,我將使用QTJ(QuickTime for Java 下同)再次解析動(dòng)畫成份。QTJ提供一個(gè)覆蓋QuickTime API的依賴對(duì)象的java,使之可以展示,編輯和創(chuàng)建QuickTime動(dòng)畫;捕獲視頻 音頻;展示2D和3D動(dòng)畫。QuickTime可用于Mac和Windows系統(tǒng)。關(guān)于QTJ的安裝.文檔和實(shí)例細(xì)節(jié)可在developer.apple.com/quicktime/qtjava查詢。由設(shè)計(jì)模式作出的推論,只在動(dòng)畫類JMFSnapper被QTSnapper取代時(shí),QTJ取代JMF在應(yīng)用中有微小的作用。圖1:兩幅QTJ情況下的3D動(dòng)畫截屏,右邊圖片采取顯示屏背面視角 從圖1大致看出,QTJ-based 和JMF成像效果沒有明顯區(qū)別。然而,通過更仔細(xì)得比較可以看出有兩個(gè)變化:QTJ動(dòng)畫有輕微的被像素化,播放的更慢。像素化(像素化是對(duì)內(nèi)部像素對(duì)于觀看者易見的數(shù)字圖像的顯示。當(dāng)一些用于普通的計(jì)算機(jī)顯示的低分辨率圖像被投射到一個(gè)大的顯示器上,每一個(gè)像素都會(huì)變得單獨(dú)可見,這種不常發(fā)生的現(xiàn)象就叫做像素化。)是由于原始動(dòng)畫從MPEG轉(zhuǎn)換為QuickTime's MOV格式引起的,它可由更好的轉(zhuǎn)換方法矯正。速度問題更基礎(chǔ):它與QTSnapper的潛在執(zhí)行有關(guān)。這篇文章的重點(diǎn)為?。執(zhí)行QTSnapper的兩種主要方法的討論.一種方法是將動(dòng)畫里的每一幀都提出來顯示在屏幕上。另一種方法依靠當(dāng)前的時(shí)間提出幀.第二種方法意味著可能將會(huì)遺漏部分幀,畫面顫抖,但遺漏 可以使播放更快。一些簡單的FPS(frame-per-second)度量器的介紹.我將用它們這兩種方法的相對(duì)速度,探測(cè)遺漏幀數(shù)1.. 此山非彼山與第一部分一樣,編碼將利用兩個(gè)大型的API,在這里沒有時(shí)間介紹利用的細(xì)節(jié)了。我將再次使用java 3D,但API媒體將由JMF轉(zhuǎn)變?yōu)镼TJ。在我的O'Reilly book, Killer Game Programming in Java (KGPJ)中有大量關(guān)于java 3D的信息,還有圖1的原碼。我將不會(huì)解釋動(dòng)畫屏幕和動(dòng)畫更新行為,因?yàn)樗鼈兣c第一部分相同。在QTJ技術(shù)中我將會(huì)使用QTSnapper從動(dòng)畫中提取幀2.應(yīng)用的兩種看法圖2:應(yīng)用流程圖 此圖表與第一篇文章中的幾乎相同QuickTime動(dòng)畫由QTSnapper類加載,動(dòng)畫屏幕由QTMovieScreen創(chuàng)建.每40毫秒,TimeBehavior對(duì)象調(diào)用QTMovieScreen中的nextFrame()方法.然后調(diào)用QTSnapper中的getFrame()方法獲取動(dòng)畫中的一個(gè)幀.依次循環(huán).JMFSnapper與QTSnapper之間有一個(gè)很重要的不同.JMFSnapper返回一個(gè)幀,這個(gè)幀是動(dòng)畫播放時(shí)的當(dāng)前幀.而QTSnapper返回動(dòng)畫中的幀根據(jù)遞增的索引.例如.當(dāng)getFrame()方法在JMFSnapper被反復(fù)調(diào)用時(shí),也許會(huì)重新得到幀1,3,6,9等等,它是由方法何時(shí)被調(diào)用與動(dòng)畫播放速度決定的.當(dāng)getFrame()方法在QTSnapper被調(diào)用,它將會(huì)返回幀1,2,3,4等等.圖3:UML類的應(yīng)用圖表,僅列出公共方法. 此圖表除了動(dòng)畫屏幕名和動(dòng)畫類名(QTMovieScreen 和 QTSnapper)外,與第一篇文章的相同.事實(shí)上,只有Snapper類的內(nèi)部執(zhí)行被改變.JMF Movie3D應(yīng)用程序和QTJ-based版本之間的改動(dòng)需要Snapper被重寫. // global variableprivate QTSnapper snapper; // was JMFSnapper// in the constructor, load the movie in fnmsnapper = new QTSnapper(fnm);這兩處改動(dòng)是由于須將JMFMovieScreen重命名為QTMovieScreen. 這個(gè)例子中的所有代碼,和文章的早期版本,可以在KGPJ website查詢到.3.一幀一幀的動(dòng)畫理解QTSnapper的內(nèi)在工作機(jī)理,可以幫助我們對(duì)QuickTime動(dòng)畫構(gòu)造有一個(gè)大致的認(rèn)識(shí).每一幅動(dòng)畫可以理解為視頻軌跡和音頻軌跡在相同時(shí)間上的重疊.圖4是這種思想的圖示 圖4:QuickTime動(dòng)畫的內(nèi)部構(gòu)造機(jī)理每個(gè)軌跡控制著其自身數(shù)據(jù),例如它包含的媒體類型和媒體本身.媒體容器(media container)有它自己的數(shù)據(jù)結(jié)構(gòu),包括它的持續(xù)時(shí)間和播放率(每秒播放抽樣數(shù)).媒體是由一組抽樣(或幀)組成,第一個(gè)抽樣時(shí)間為0(與媒體時(shí)間有關(guān)).抽樣是被變址的,第一個(gè)抽樣在1位置(非0).圖5大致描述了QuickTime的軌跡和媒體結(jié)構(gòu) 圖5:QuickTime軌跡和媒體的內(nèi)在構(gòu)造機(jī)理想要得到更多信息,請(qǐng)查詢QuickTime指南的movie section打開動(dòng)畫視頻媒體QTSnapper構(gòu)造器打開動(dòng)畫:// globalsprivate boolean isSessionOpen = false;private OpenMovieFile movieFile;private Movie movie;// in the constructor,// start a QuickTime sessionQTSession.open();isSessionOpen = true;// open the moviemovieFile = OpenMovieFile.asRead( new QTFile(fnm) );movie = Movie.fromFile(movieFile);在QuickTime使用之前調(diào)用QTSession.open()方法將其初始化.在終止時(shí)相應(yīng)的調(diào)用QTSession.close()方法.軌跡定位和媒體訪問// more globalsprivate Track videoTrack;private Media vidMedia;// in the constructor, // extract the video track from the movievideoTrack = movie.getIndTrackType(1, StdQTConstants.videoMediaType, StdQTConstants.movieTrackMediaType);if (videoTrack == null) { System.out.println('Sorry, not a video'); System.exit(0);}// get the media used by the video trackvidMedia = videoTrack.getMedia();一旦媒體打開,從中提取各種信息// more globalsprivate MediaSample mediaSample;private int numSamples; // number of samplesprivate int sampIdx; // current sample indexprivate int width; // frame widthprivate int height; // frame height// in the constructornumSamples = vidMedia.getSampleCount();sampIdx = 1; // get first sample in the trackmediaSample = vidMedia.getSample(0, vidMedia.sampleNumToMediaTime(sampIdx).time,1);// store width and height of image in the sampleImageDescription imgDesc = ImageDescription) mediaSample.description;width = imgDesc.getWidth();height = imgDesc.getHeight();sampIdx作為計(jì)數(shù)器將在抽樣中被重復(fù)調(diào)用(抽樣于位置1開始).動(dòng)畫圖像的寬度和高度由第一個(gè)抽樣獲得,接下來所有的抽樣都是同樣的尺寸.測(cè)算 FPS由QTSnapper返回的 幀數(shù)/秒 將在稍后被用作類的不同使用方法的比較參數(shù).構(gòu)造器中必要的參數(shù)已被初始化. // frame rate globalsprivate long startTime;private long numFramesMade;// initialize them in the constructorstartTime = System.currentTimeMillis(); numFramesMade = 0;結(jié)束將應(yīng)用程序結(jié)束時(shí),QTSnapper類中的stopMovie()方法將被調(diào)用.它報(bào)告FPS,關(guān)閉QuickTime.// globalsprivate DecimalFormat frameDf = new DecimalFormat('0.#'); // 1 dpsynchronized public void stopMovie(){ if (isSessionOpen) { // report frame rate long duration = System.currentTimeMillis() - startTime; double frameRate = ((double) numFramesMade*1000.0)/duration; System.out.println('FPS: ' + frameDf.format(frameRate)); QTSession.close(); // close down QuickTime isSessionOpen = false; }}由于stopMovie()和getFrame()是同步的,所以從動(dòng)畫中提取幀和QuickTime關(guān)閉在時(shí)間上是不可能同時(shí)進(jìn)行.緩存幀getFrame()返回一次抽樣樣品,稱作BufferedImage對(duì)象.被選擇的幀利用索引指數(shù)存貯在sampIdx.// globalsprivate BufferedImage img, formatImg;synchronized public BufferedImage getFrame(){ if (!isSessionOpen) return null; if (sampIdx> numSamples) // start back with the first sample sampIdx = 1; try { /* Get the sample starting at the specified index time */ TimeInfo ti = vidMedia.sampleNumToMediaTime(sampIdx); mediaSample=vidMedia.getSample(0,ti.time,1); sampIdx++; writeToBufferedImage(mediaSample, img); // resize img, writing it to formatImg Graphics g = formatImg.getGraphics(); g.drawImage(img, 0, 0, FORMAT_SIZE, FORMAT_SIZE, null); // Overlay current time on image g.setColor(Color.RED); g.setFont( new Font('Helvetica', Font.BOLD, 12)); g.drawString(timeNow(), 5, 14); g.dispose(); numFramesMade++; // count frame } catch (Exception e) { System.out.println(e); formatImg = null; } return formatImg;} // end of getFrame()從QTJ的媒體類中調(diào)用getSample()方法可以容易的獲得抽樣.不幸的是,將抽樣轉(zhuǎn)化為BufferedImage仍然是個(gè)棘手的問題.豐富的細(xì)節(jié)和注釋,可以在編碼中研究.從抽樣種萃取一個(gè)“原始圖像,然后將其減壓寫成一個(gè)QuickTime版本的Graphics對(duì)象.Graphics對(duì)象中的無壓縮數(shù)據(jù)被拷貝成為另一個(gè)“原始圖像,然后成為一個(gè)像素?cái)?shù)組.最后,這個(gè)數(shù)組被寫入空BufferedImage的DataBuffer.程序能工作嗎?能順利工作嗎? 是的,Movie3D顯示動(dòng)畫,但是比較大的動(dòng)畫播放的比較慢.這是由于getFrame()方法在幀補(bǔ)給上的緩慢,它可以通過FPS數(shù)量進(jìn)行量化.對(duì)于圖1的動(dòng)畫,在Windows 98系統(tǒng)FPS之大概在15-17幀/秒.然而,TimeBehavior對(duì)象要求每40毫秒更新,轉(zhuǎn)化為幀數(shù)大概在25FPS.getFrame()方法之所以慢是由于抽樣轉(zhuǎn)化為BufferedImage的時(shí)間消耗.由于當(dāng)前調(diào)用的getFrame()方法在轉(zhuǎn)化幀時(shí)停頓,更多的請(qǐng)求將被延遲直到當(dāng)前轉(zhuǎn)化完成.我將考慮兩種解決這一問題的方法:允許getFrame()方法在處理請(qǐng)求時(shí)遺漏幀,和在getFrame()方法中使用不同的轉(zhuǎn)化方法.我將輪流考慮這兩種方法,以幀遺漏開始.4. 遺漏幀的動(dòng)畫新的Snapper類,QTSnapper1,仍然返回一個(gè)幀當(dāng)getFrame()方法被調(diào)用時(shí).與QTSnapper的不同在于它提供的類相應(yīng)于當(dāng)前動(dòng)畫的執(zhí)行時(shí)間.例如,getFrame()也許重新獲得幀1,2,5,8,14等等,依賴于方法的調(diào)用時(shí)間.因此,動(dòng)畫以一個(gè)很好的速度播放,但是由于幀的遺漏可能導(dǎo)致畫面顫抖.對(duì)比的看,QTSnapper將會(huì)返回所有的幀數(shù)(1,2,3,4等等),但是由于調(diào)用getFrame()方法的延遲可能會(huì)導(dǎo)致動(dòng)畫播放緩慢.然而,畫面將不會(huì)出現(xiàn)顫抖,由于沒有幀被遺漏.QTSnapper1種的關(guān)鍵部分是對(duì)于動(dòng)畫的“當(dāng)前執(zhí)行時(shí)間理念.我的方法是當(dāng)getFrame()方法被調(diào)用估計(jì)QTSnapper的當(dāng)前執(zhí)行時(shí)間,將它轉(zhuǎn)變?yōu)閯?dòng)畫執(zhí)行時(shí)間,然后作為樣本給定值.QTSnapper1有與QTSnapper相同的公共方法,所以它只需作出微小的改變就可用于QTMovieScreen.只有在動(dòng)畫播放時(shí)差別才變得明顯,在以很好的速度播放時(shí)會(huì)發(fā)出喳喳聲.詳細(xì)的測(cè)量,以圖1的“明顯幀率比較,31FPS對(duì)比QTSnapper的16FPS.打開動(dòng)畫視頻媒體QTSnapper1訪問動(dòng)畫視頻的過程與QTSnapper相同.一旦視頻可被利用,個(gè)別的媒體值將被儲(chǔ)存并稍后被getFrame()方法調(diào)用:// globalsprivate Media vidMedia;private int numSamples;private int timeScale; // media's time scaleprivate int duration; // duration of the media// in the constructor,// get the media used by the video trackvidMedia = videoTrack.getMedia();// store media details for laternumSamples = vidMedia.getSampleCount();timeScale = vidMedia.getTimeScale();duration = vidMedia.getDuration();獲取一幀getFrame()方法中的新要素是它怎樣計(jì)算被用于訪問詳悉抽樣的給定值.方法的其他部分,writeToBufferedImage()的調(diào)用和當(dāng)前圖像的編碼與QTSnapper相同. // globalsprivate MediaSample mediaSample;private BufferedImage img, formatImg;private int prevSampNum;private int sampNum = 0;private int numCycles = 0;private int numSkips = 0;// inside getFrame(),// get the time in secs since start of QTSnapper1double currTime = ((double)(System.currentTimeMillis() - startTime))/1000.0;// use the video's time scaleint videoCurrTime = ((int)(currTime*timeScale)) % duration;try { // backup the previous sample number prevSampNum = sampNum; // calculate the new sample number sampNum = vidMedia.timeToSampleNum( videoCurrTime).sampleNum; // if no sample change, then don't generate // a new image if (sampNum == prevSampNum) return formatImg; if (sampNum < prevSampNum) numCycles++; // movie has just started over // record the number of frames skipped int skipSize = sampNum - (prevSampNum+1); if (skipSize> 0) // skipped frame(s) numSkips += skipSize; // get a single sample starting at the // sample number's time TimeInfo ti = vidMedia.sampleNumToMediaTime(sampNum); mediaSample = vidMedia.getSample(0,ti.time,1);getFrame()在很短的時(shí)間內(nèi)計(jì)算當(dāng)前時(shí)間,從QTSnapper1開始時(shí)測(cè)量:double currTime = ((double)(System.currentTimeMillis() - startTime))/1000.0;每一個(gè)QuickTime的媒體片斷都有它自己的時(shí)間刻度,ts,例如一個(gè)個(gè)體的時(shí)間是1/ts 秒.恒定的時(shí)間刻度必須由currTime方法增加以獲得當(dāng)前動(dòng)畫時(shí)間.int videoCurrTime = ((int)(currTime*timeScale)) % duration;以媒體持續(xù)時(shí)間為模校正刻度時(shí)間,允許動(dòng)畫在當(dāng)前時(shí)間已超過動(dòng)畫結(jié)束時(shí)間重復(fù).調(diào)用Media's timeToSampleNum()方法將抽樣序列數(shù)以刻度時(shí)間顯示:sampNum = vidMedia.timeToSampleNum( videoCurrTime).sampleNum;上次抽樣序列號(hào)存儲(chǔ)在prevSampNum,以便允許實(shí)現(xiàn)大量的檢測(cè)和計(jì)算.如果新的抽樣序列號(hào)與上次取樣的序列號(hào)相同,就不需要檢查將抽樣轉(zhuǎn)化為BufferedImage的過程;getFrame()可以返回現(xiàn)有的formatImg接口.如果新的抽樣序列號(hào)小于上次取樣的序列號(hào),這就意味著動(dòng)畫開始循環(huán),動(dòng)畫起始幀將被顯示.這就是被注冊(cè)的numCycles增加.如果新的抽樣序列號(hào)大于上次取樣的序列號(hào)+1,意味著被遺漏的幀序列被記錄上.結(jié)束stopMovie()打印出FPS,關(guān)閉QuickTime進(jìn)程,與QTSnapper類中的stopMovie()方法相同.同時(shí)它也報(bào)告附加信息: long totalFrames = (numCycles * numSamples) + sampNum;// report percentage of skipped framesdouble skipPerCent = (double)(numSkips * 100) / totalFrames;System.out.println('Percentage frames skipped: '+ frameDf.format(skipPerCent) + '%');// 'apparent' FPS (AFPS)double appFrameRate = ((double) totalFrames * 1000.0) / duration;System.out.println('AFPS: ' + frameDf.format(appFrameRate)); // 1 dpappFrameRate方法描述“顯性幀頻,就是從QTSnapper1開始使用時(shí)的抽樣總量.感覺上的“顯性 是因?yàn)椴皇撬械某闃佣加斜伙@示出來的必要.程序能工作嗎?能順利工作嗎?QTSnapper被QTSnapper1取代后,緩慢的動(dòng)畫(圖1所示)將會(huì)播放的更快.結(jié)束時(shí)間時(shí),據(jù)報(bào)告的明顯幀頻是31FPS,實(shí)際上的幀頻大概在16FPS,遺漏頻大概占總數(shù)的50%.驚奇的是,大量遺漏頻的并沒有顯示在屏幕上.對(duì)與另外一些比較小的動(dòng)畫,速度的增加幾乎是察覺不到的;遺漏頻率大概在5%-10%.不幸的是,仍然還有兩個(gè)問題:幀遺漏產(chǎn)生的雜亂像素和對(duì)遺漏幀的數(shù)量的控制.雜亂像素?zé)o論何時(shí),只要QTSnapper1遺漏一個(gè)動(dòng)畫幀,下一個(gè)幀將會(huì)包含一些雜亂像素.圖6是效果顯示圖.從一段早期視頻截得的錯(cuò)誤像素使用值. 圖6 雜亂圖像截屏問題是我所有的視頻事例都是使用temporal compression,它是一種利用連續(xù)視頻幀之間類似處的一種壓縮方法.假如兩個(gè)連續(xù)視頻幀有相同的背景,就不用再次存儲(chǔ)背景.只有兩個(gè)幀之間的不同才會(huì)被存儲(chǔ).這項(xiàng)技術(shù),被用在幾乎所有的流行視頻格式,意味著從一個(gè)幀中抽取圖像依賴這個(gè)幀和此前的幾個(gè)幀.暫時(shí)解壓由在writeToBufferedImage()方法中的QuickTime DSequence對(duì)象處理.DSequence構(gòu)造器詳細(xì)說明了QuickTime在解壓過程中應(yīng)該使用的一種屏幕外圖像緩沖器.幀圖像被寫入緩沖器,在那里與早期的幀數(shù)據(jù)結(jié)合.結(jié)合后圖像被傳給轉(zhuǎn)化的下一過程.QTSnapper1順次解壓時(shí)工作的很好,沒有遺漏幀,但是如果產(chǎn)生遺漏會(huì)導(dǎo)致錯(cuò)誤.例如,當(dāng)QTSnapper1遺漏幀5和6,然后解壓幀7時(shí)會(huì)發(fā)生什莫?幀被寫入QuickTime圖像緩沖器,與此前幀的數(shù)據(jù)結(jié)合.然而,幀5和6的數(shù)據(jù)丟失,所以結(jié)合后的圖像會(huì)有錯(cuò)誤.簡單的講,圖像中的雜亂像素是由動(dòng)畫的暫時(shí)壓縮引起的.一個(gè)可選擇的辦法是使用空間壓縮技術(shù),既獨(dú)立的壓縮每個(gè)幀.這就意味著解壓時(shí)幀里所有的信息都會(huì)從幀本身被釋放出來,不需要檢查早期的幀.QuickTime MOV支持名為Motion-JPEG(M-JPEG)的空間壓縮方案.我使用QuickTime 6 Pro 中的工具將圖1以M-JPEG A編碼形式存儲(chǔ)為MOV文件.當(dāng)這個(gè)動(dòng)畫用Movie3D播放時(shí),沒有發(fā)生畫面顫抖.限制幀遺漏QTSnapper1的另一個(gè)問題時(shí)getFrame()沒有對(duì)可能遺漏幀的數(shù)量進(jìn)行限制.在我的測(cè)試中,遺漏幀的數(shù)量被限制在3個(gè)以下.然而,如果getFrame()用于一個(gè)很大抽樣的轉(zhuǎn)化,那末它的緩慢增加將會(huì)導(dǎo)致更多幀的遺漏.動(dòng)畫質(zhì)量將會(huì)發(fā)生明顯的惡化.5. 試著使圖像更快在QTSnapper和QTSnapper1中使用的sample-to-BufferedImage轉(zhuǎn)換方法(writeToBufferedImage())是由Chris W. Johnson在實(shí)例中獲得的.有沒有一種更快的從抽樣中隨取圖像的方法呢?QTJ方面的權(quán)威書籍:QuickTime for Java: A Developer's Notebook,作者:Chris Adamson, O'Reilly,2005.1月出版.卷五,covering QuickDraw,中的ConvertToJavaImageBetter.java實(shí)例,展示了怎樣獲得一個(gè)PICT圖像的抽樣并將其轉(zhuǎn)化為Java圖像對(duì)象.這個(gè)例子也可在quicktime-java mailing list中找到.我使用Adamson碼作為另一個(gè)Snapper類的編碼基礎(chǔ),稱之為QTSnapper2.它可以無遺漏的返回幀,與QTSnapper的方法一樣,但是使用PICT-to-Image轉(zhuǎn)化.在一部小動(dòng)畫中,QTSnapper2與QTSnapper的表現(xiàn)沒有區(qū)別,但對(duì)于比較大的動(dòng)畫例如例1,它的平局幀頻大概為9FPS,對(duì)比與QTSnapper的16FPS.換句話說,PICT-based轉(zhuǎn)化慢于Johnson技術(shù)--------------------------------------------------------------------------------------Andrew Davison 是個(gè)教育者,研究員,及作家。以前曾在墨爾本大學(xué)的計(jì)算機(jī)科學(xué)部門工作,現(xiàn)居住在泰國,并在Prince of Songkla大學(xué)任教。 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 3D世界的動(dòng)畫展示(Part2,使用QuickTime for Java)作者: Andrew Davison 翻譯 Caesh版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 亚洲日本高清成人aⅴ片 | 精品国产自在现线看久久 | 在线观看亚洲成人 | 99久久免费精品视频 | 亚洲天堂久久久 | 日韩中文字幕在线观看 | 91麻精品国产91久久久久 | 欧美黄色一级在线 | 三级黄色在线 | 91精品国| 日韩精品一区二区三区中文字幕 | 亚洲成人在线视频网站 | 日本不卡一区二区三区在线观看 | 日本精品中文字幕有码 | 国产精品久久九九 | 美女午夜色视频在线观看 | 久久久一区二区三区 | 性欧美f| 鲁丝一区二区三区不属 | 日韩欧美中文字幕一区二区三区 | 亚洲一区二区在线免费观看 | 国产亚洲精品久久久久久 | 国产乱理片在线观看夜 | 一级亚洲| 九九99久久| 一级成人毛片免费观看 | 欧美成人免费观看久久 | 亚洲成a人片在线网站 | 天天爱天天做天天爽天天躁 | 不卡的毛片 | 欧美久久久久欧美一区 | 欧美亚洲日本在线 | 三a毛片| 精品国产成人综合久久小说 | 亚洲国产成人久久 | 欧美一级一一特黄 | 在线私拍国产福利精品 | 成人久久久观看免费毛片 | 久久久久久久久中文字幕 | 久草视频福利资源站 | 亚洲黄色在线播放 |