全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1766
推到 Plurk!
推到 Facebook!

[推薦] 粒子系統在2D特效中的應用(全)

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-08-14 16:59:35 IP:61.218.xxx.xxx 未訂閱

粒子系統在2D特效中的應用(全)

-------------------------------------------------------------------------------- by: 劉小軍 Last Updated: Mar-22-2001 | First Version:Jan-29-1999 資料來源:http://www.cpp3d.com/downloads/ Particles01源碼 (25K) -------------------------------------------------------------------------------- 粒子系統是啥西?小軍曰:所謂的粒子系統,就是將我們看到的物體運動和自然現象,用一系列運動的粒子來描述,再將這些粒子運動的軌跡映射到顯示屏上,然后呢?就是我們在顯屏上看到的物體運動和自然現象的模擬效果了。 利用粒子系統我們可以在屏幕中表現諸多的特殊效果,如:焰火、火苗、落葉、雪花飛舞等。不怕做不到,就怕想不到。只要你的想象力足夠豐富,你可以創造出意想不到的奇跡來。 好,開始切入我們這章的主題,粒子系統應用的關鍵在于如何描述粒子的運動軌跡,也就是構造粒子的運動函數。函數選擇的恰當與否,決定效果的逼真程度。其次坐標系的選定(就是視角啦)也有一定的關系,視角不同,看到的效果自然不一樣了。在這章里,我會用很多的實例來解釋如何應用粒子系統來實現各種特效。接下來我們要實現的第一種特效就是------ 運動圖標(一) 圖標在這里我們泛指所有的位圖,如團體標識、文字等圖象。這里要實現的是讓圖標從遠處迎面快速飛來這麼一種效果。下面的同學別起哄,我要給你們演示的不是Windows的飛行窗口,它太缺乏速度感了,你們要感受的將是迎面碰撞的效果。下面我們一步一步來實現它: 第一步:構造粒子 一幅位圖可看作是現實世界中的一張相片,我們看到的是它(位圖)在與我們視線垂直的平面(顯屏)上的投影。因此可用{長*寬}個單元的數組來描述,每個單元是一個點的顏色,畫到屏幕上之前先計算好每個點在顯屏上投影的位置就可以了。但我們凡事都要首先考慮一下效率。因為我們的圖標一般都會設一個ColorKey,也就是透明色,位圖中與顏色值與ColorKey相同的點都不需要畫到顯屏上,該顏色在屏幕上看起來就成了透明的。而我們計算各點運動軌跡的計算量可能都不會小,且透明色在整個位圖中占的比例也一般較大,大量透明點參與運算勢必影響程序的整體效率。所以我們要採取內存換效率的辦法,犧牲少量的內存,爭取更高的執行效率。具體辦法是將數組中的透明點拿走,再給非透明點增加一些位置信息。 粒子系的生成過程是:先計算非透明點總數,再為這些點申請內存,最后讀入每個的位置、顏色信息。 第二步:計算粒子在屏幕上的投影位置 我們這里圖標是沿視線方向運動的,所以可讓坐標系的Z軸沿視線方向,X、Y軸與屏幕的X、Y軸相同即可。目標從遠處移近時,眼睛看到是從小到大,不斷加速變大的物體形象。所以可用一個比例因子來描述這種變化。將圖標的運動分成幾個時段,依次在每個時段加大比例因子的增量,粒子的投影坐標就取其實際坐標(也就是其對應于原始位圖的點坐標)與比例因子之積就行了。 第三步:畫粒子 第四步:重複第二、三步過程 以下代碼應該很容易讀懂:
    // Code in Particles.h        class Cparticles          {        private:            struct PARTICLE{            int     X0, Y0;  // 點在位圖中的坐標            DWORD   dwColor;            int     X, Y;    // 點投影到屏幕上的坐標            };        public:            Cparticles();            virtual ~Cparticles();            BOOL Create(CDDSurface *pDds);            VOID ServeParticles();            VOID Draw(LPDDSURFACEDESC2 pDdsd, int nX=0, int nY=0);        protected:            DWORD       m_dwCnt;            PARTICLE    *m_pPtc;            int         m_nScale;        };        // Code in Particles.cpp        // 生成粒子系。方便起見,取位圖左上角第一個點的顏色值為ColorKey        BOOL Cparticles::Create(CDDSurface *pDds)        {            DWORD dwColorKey;            DWORD dwBPP;            DWORD dwMask;            DDSURFACEDESC2 ddsd;            ddsd.dwSize = sizeof(DDSURFACEDESC2);            if (pDds->Lock(&ddsd) != DD_OK)                return FALSE;            dwBPP = ddsd.ddpfPixelFormat.dwRGBBitCount>>3;   // Bytes per pixel            switch (dwBPP)            {            case 1:                dwMask = 0xFF;                break;            case 2:                dwMask = 0xFFFF;                break;            case 3:                dwMask = 0xFFFFFF;                break;            case 4:                dwMask = 0xFFFFFFFF;            }            dwColorKey = (*((DWORD *)ddsd.lpSurface)) & dwMask;            BYTE *pS = (BYTE *)ddsd.lpSurface;            for (DWORD I=0; IUnlock();                return FALSE;            }            m_pPtc = new PARTICLE[m_dwCnt];            if (m_pPtc == NULL)        // No enough memory            {                pDds->Unlock();                return FALSE;            }            // Make Particles            pS = (BYTE *)ddsd.lpSurface;            m_dwCnt = 0;            for (I=0; I>1);                        m_pPtc[m_dwCnt].Y0 = I-(ddsd.dwHeight>>1);                        m_dwCnt  ;                    }                    pS =dwBPP;                }            pDds->Unlock();            return TRUE;        }        // 計算粒子的新位置        VOID Cparticles::ServeParticles()        {            DWORD    I;            int      Scale;                        // compute scaling factor            if(m_nScale < 100)            {                Scale = m_nScale;                m_nScale  = 10;            }            else if(m_nScale < 200)            {                Scale = 100;                m_nScale  = 5;            }            else if(m_nScale < 5000)            {                Scale = m_nScale-100;                m_nScale  = m_nScale/10;            }            else            {                m_nScale = 0;                Scale = 0;            }                        // move each pixel            for(I=0; I=(int)pDdsd->dwWidth)|(y>=(int)pDdsd->dwHeight))                    ;                else                {                    BYTE *sfc = (BYTE*)pDdsd->lpSurface                         y*pDdsd->lPitch                         x*pDdsd->ddpfPixelFormat.dwRGBBitCount/8;                    switch (pDdsd->ddpfPixelFormat.dwRGBBitCount)                    {                    case 4:                        break;                    case 8:                        *sfc = (BYTE)m_pPtc[I].dwColor;                        break;                    case 16:                        *((WORD*)sfc) = (WORD)m_pPtc[I].dwColor;                        break;                    case 24:                        *((WORD*)sfc) = (WORD)m_pPtc[I].dwColor;                        sfc  = 2;                        *sfc = (BYTE)(m_pPtc[I].dwColor>>16);                        break;                    case 32:                        *((WORD*)sfc) = (WORD)m_pPtc[I].dwColor;                        sfc  = 2;                        *((WORD*)sfc) = (WORD)(m_pPtc[I].dwColor>>16);                        break;                    }                }            }        }
小節:這一節我們討論了一個簡單運動圖標的實例,大家對粒子系統應該有一個初步的了解了。如果讓圖標的運動更複雜一些會是什麼效果呢?………… Particles02源碼 (18K) -------------------------------------------------------------------------------- 前面我們的運動圖標應該是粒子系統運用中比較簡單的一種了,這也是我在游戲月亮之子里見到過的一種特效,這種特效是通過一系列的數學運算而產生的動態圖像效果。在特效的實現過程當中還有一種是通過對現實事物的模仿演變而成的。在月亮之子這個游戲中還有一種特效,就是漂浮的煙霧,慢慢成型,演變成精靈圖像。這種特效我與方泓曾討論過多次,盡管我們不知道月亮之子的作者具體是如何實現這一特效的,但我們通過不斷研究學習,覺得其實現原理應該屬繩索模擬的變種,這里我們將學習的一些心得寫出來供大家參考,希望對大家有所幫助。源碼編譯需DX6或以上SDK,VC,DXGuide。 運動圖標(二) 在開始之前,我們先來簡單介紹一下粒子系統中的另一種應用--繩索模擬,比如說我們拽住一根繩索的一端,不停用力抖動,力沿繩索往后傳,于是整根繩索也隨著擺動起來了。繩索可看成是由彈簧連接的若幹粒子組成,這樣就可以通粒子系統來模擬繩索的運動了。繩索模擬在游戲當中有很多的應用,如地蟲阿占手中揮動的啪啪作響的長鞭和劃過夜空的流星等,都可用繩索模擬來實現。但是我們這里並不是要模擬繩索類的東西,而是要描述圖標(或精靈)的變幻運動。它們之間有什麼聯系呢?其實我們可將圖標(或精靈)象素點的行或列看作是一根根獨立的繩索,再讓它們運動起來…… 是不是找到感覺了,好了,我們開始吧!首先我們來構造繩索運動算法,假定繩索是由N個點組成,外力作用在第一個點上,繩索的運動可以這樣描述: 在外力作用下,第一點開始移動,偏移量為(dx0, dy0),其它點不動 在張力的作用下,力由第一點傳到第二點,第二點也開始移動,偏移為(dx0, dy0),另外因外力繼續作用,第一點又偏移(dx1, dy1),其它點不動 力繼續往后傳,第二點的力傳到第三點,第三點偏移(dx0, dy0),第二點偏移(dx1, dy1),同時第一點再次偏移(dx2, dy2),其它點不動 接下來是第四點、第五點等各點依次活動起來,只要外力不撤消,整根繩索就不停運動…… 外力撤消,第一個點首先停止運動,接著第二點、第三點直至所有點都依次停止運動。 這就是一個最簡單的繩索運動過程,這里有很多內在和外在的因素都沒加以考慮,如質量、重力、力衰減等。因為我們要做的僅僅是運動圖標而已,這樣就已經足夠了,下次有時間的話我會作一個更象樣一點的繩索模擬應用,這里暫時就只引入繩索模擬的這個簡單實現方法。以上繩索運動的實現代碼如下:
class
Cparticle
 {
 public:
         Cparticle(){Next = NULL; xv = 0; yv = 0;};
         ~Cparticle(){};
              Cparticle        *Next;
         double                x, y;
         double                xv, yv;
         DWORD                dwColor;
 };
      class Cstrings
 {
 public:
         Cstrings();
         ~Cstrings();
 
         Cparticle        *m_pPtcs;
 
        //DWORD                m_dwCount;
         virtual        void AddPtc(double x, double y, DWORD color);
 
        virtual void Move(double dx, double dy);        // First particle move to (x dx,
y dy)
         virtual void Draw(LPDDSURFACEDESC2 pdesc);
 };
 
 Cstrings::Cstrings():
 
m_pPtcs(NULL)
 {
 }
 
 Cstrings::~Cstrings()
 {
         Cparticle *pPtc;
         while
(m_pPtcs != NULL)
         {
                 pPtc = m_pPtcs;
                 m_pPtcs = m_pPtcs->Next;
                 delete
pPtc;
         }
 }
 
 void Cstrings::AddPtc(double x, double y, DWORD color)
 {
 
        Cparticle *pPtc = new Cparticle;
         pPtc->x = x; pPtc->y = y; pPtc->dwColor
= color;
         pPtc->Next = NULL;
         if (m_pPtcs == NULL)
                 m_pPtcs = pPtc;
 
        else
         {
                 Cparticle *ptc = m_pPtcs;
                 while(ptc->Next!=NULL)
                 {
 
                        ptc = ptc->Next;
                 }
                 ptc->Next = pPtc;
         }
 }
 
 void Cstrings::Move(double
dx, double dy)
 {
         Cparticle *pPtc = m_pPtcs;
         double x0, y0, x1, y1;
         x1
= dx; y1 = dy;
         while (pPtc)
         {
                 x0 = pPtc->xv;
                 y0 = pPtc->yv;
 
                pPtc->xv = x1;
                 pPtc->yv = y1;
                 x1 = x0;
                 y1 = y0;
                 pPtc
= pPtc->Next;
         }
 
         pPtc = m_pPtcs;
         while (pPtc)
         {
                 pPtc->x
 = pPtc->xv;
                 pPtc->y  = pPtc->yv;
                 pPtc = pPtc->Next;
         }
      }
 
 void Cstrings::Draw(LPDDSURFACEDESC2 pdesc)
 {
         BYTE *pWord;
         Cparticle
*pPtc = m_pPtcs;
         while(pPtc)
         {
                 if (pPtc->xdwWidth
&& pPtc->ydwHeight && pPtc->x>=0 &&
pPtc->y>=0)
                 {
                         pWord = (BYTE*)pdesc->lpSurface;
                         pWord =
(int)pPtc->y*pdesc->lPitch   (int)pPtc->x*sizeof(WORD);
                         *((WORD*)pWord)
= (WORD)pPtc->dwColor;
                 }
                 pPtc = pPtc->Next;
         }
 }
 
 
繩索運動實現之后,運動圖標也就好實現了,具體過程如下: 將圖標位圖讀入 以每行或每列的象素點作為一條條繩索上的點構造繩索 讓繩索按各自軌跡運動起來(施加外力),顯示出來就形成千變萬化的煙霧了。 讓繩索停下來(撤消外力),則顯現圖標(或精靈)的原形 實現代碼如下:
class Clogo    {    public:            Clogo();            ~Clogo();            Cstrings        *m_pStr;            DWORD                m_dwCount;            virtual                void Create(CDDDIBSurface *pDib);            virtual                void Init();            virtual                void Service();            virtual                void Draw(LPDDSURFACEDESC2 pddsd);    };        Clogo::Clogo():    m_pStr(NULL),    m_dwCount(0)    {    }        Clogo::~Clogo()    {            if (m_dwCount)            {                    delete [] m_pStr;                    m_dwCount = 0;            }    }        void Clogo::Create(CDDDIBSurface *pDib)    {            DDSURFACEDESC2 ddsd;            ddsd.dwSize = sizeof(DDSURFACEDESC2);            m_dwCount = pDib->GetWidth();            m_pStr = new Cstrings[m_dwCount];            pDib->Lock(&ddsd);
        for (DWORD I=0; I< pDib->GetHeight(); I  )                    for (DWORD j=0; jGetPixel(&ddsd,j,I));            pDib->Unlock();    }        void Clogo::Init()    {            Cparticle *pPtc;            int y;            for (DWORD x=0; xx = 640 x*4;                            pPtc->y = 320 y;                            pPtc->xv = 0;                            pPtc->yv = 0;                            y  ;                            pPtc = pPtc->Next;                    }            }    }        void Clogo::Service()    {    //        static int t = 0;            static double x = 0;            static double y = 0;            double y1 = y;            x  ;            y = 3*sin(x*3.1415927/90);            double dy = y-y1;            if (x<=400)                    for (DWORD I=0; I600)            {                    x = 0;                    y = 0;                    Init();            }        //        t  ;    }        void Clogo::Draw(LPDDSURFACEDESC2 pddsd)    {            for (DWORD I=0; I    因試驗目的,上面繩索運動函數未精心選取,不過本文的目的是探索實現的方法,效果的好壞應在其次。你可以看完本文之后自己加以改進優化,讓它看起來更cool。    你可以下載本實例的源碼,編譯需VC  5.0或以上、DXGuide,DirectX SDK。    總結:通過兩個粒子系統的具體實例,我們不難發現粒子應具備如下的一個或多個特征:     位置 
速度和方向 
加速度 
生命值
第一個和第二個特征已經接觸過,加速度和生命值也將在以后介紹,加速度不難理解,生命值是指粒子消逝時間值,如煙火中的顆粒,一段時間之后就熄掉了,這種顆粒能夠保持可見的時間值就稱為生命值。         snow源碼 (13K)    --------------------------------------------------------------------------------
 
原本不想寫這篇文章的,因為到目前為止我對它的效果還不是很滿意,不過后來我想可能有人需要它,所以還是把它作為第三個粒子系統應用放在這里了。    落雪    之所以我們可以用粒子系統來實現落雪的特效,是因為我們可以用粒子來模擬雪花的運動。在開始之前我們先來想象一下下雪的情景(南方的朋友請原諒),漫天的雪花從空中徐徐飄下,此時你可能正漫步街頭,你也可能正佇立窗前,但不管你在哪里,細心的你可能已經發現飄落的雪花形狀各不相同,有些在空中飄飄蕩蕩,隨風起舞,而有些則倏地從你眼前一閃而落,消失在茫茫雪色之中。往往有許多惆悵和失意在這種季節產生,不過現在已是春曖花開,雪是沒了,不過我們還可以通過自己的想象,來造一場雪景。根據我們的經驗,可以大致得出這樣的結論──    要使我們的雪下得真實,至少必須符合以下六點:     雪花有不同的形狀或大小 
雪花不是直線落下的,受空氣阻力會到處飄蕩 
雪花受空氣阻力不同,其下落速度也不同 
雪花因視覺關系,離我們越遠看起來感覺越小 
雪有時下得大,有時下得小 
下雪時,有時會刮風
如果你把以上六點都全面地考慮進去了,那麼你造的雪景一定會很成功。下面我們一點一點來說明如何來實現它們:    雪花的粒子描述可包括以下各項:屏幕坐標(x, y)、視覺深度z、速度(xv, yv)、形狀位圖pDIB。    因重力基本與空氣阻力平衡,為方便起見,加速度可忽略不計。    雪花形狀可以通過定制不同形狀的位圖來實現,雪花的大小可根據視覺深度,選擇相應的位圖來實現。    雪花在空中的下落速度yv可構造適當的隨機函數來實現,而飄蕩效果的實現可通過構造適當的函數,以(x, y, z)為自變量來不停改變雪花的水平速度xv。這樣,雪花在下落的同時會在空中左右飄蕩。    視覺的深度效果比較難實現,最簡單的辦法是用數組或鏈表。比如我們可以將雪花劃分成5個層次,第1層離我們最遠,第2層離我們近一些……最近一層是第5層,我們隨機產生雪花時讓z值的隨機值為0~4,將z值為0的放到第1層,將z值為1的放到第2層……將z值為4的放到第5層。那麼從第1層到第5層,雪花的下落速度yv是越來越快,飄蕩的幅度MAX(ABS(xv))也越來越大。雪花畫到屏幕時是先畫第1層,最后畫第5層。這樣處理后的雪花看起來就比較有立體效果。    雪的大小可通過控制雪花(粒子)的數目來實現,而風的效果則可控制雪花(粒子)的速度來實現。    是不是很簡單,其實說說簡單,做起來就不那麼簡單了。我們給出的例子僅僅是例子而已,很多地方都做得很粗糙,有興趣的可下載源碼,然后自己加以改進,如果你認為效果有所改觀的話,煩請Mail一份給我。                 particles04源碼 (14K)    --------------------------------------------------------------------------------
 

火焰

我不知道這篇文章該以什麼做模型,云、煙、火還是霧,原來打算寫霧的,臨時又改變主意寫火焰。Why?因為我前些時候寫過一篇火焰的文章,記得嗎?之所以再寫火焰,是想通過兩種不同的方法的比較,讓大家體會一下粒子系統究竟有多大的魅力。大家可下載例程源碼,好吧,Let's Go。 思路: 記得物理老師常說:“物質組成的最小單位是XX,物質都是由XX構成的”。這里我仍要大家記住的是:“自然現象的變化往往都可分解成粒子群的運動來體現”。所以我們把火焰看作是火星或火花(粒子)的集合,火星(粒子)則是一個里熱外暗的光點。是不是太簡單了點?接著看下去吧,你不會失望的。 實現 構造調色板 因為我想在16bit下做sample,所以根據火的明暗強度要預先構造一個16bit的調色板。如果做單一的火焰,在8bit下要更方便些,但16bit畢竟是主流,況且我們的火焰可能不還要放到色彩較豐富的背景上去,所以我仍選擇了16bit。這里我們需要從暗到亮的一個256色的調色板。 構造粒子 火星主要有以下三個屬性或特征:位置、運動速度和生命值。粒子是在原點(見左圖)附近的X軸上隨機生成的,sample中初始時x取-100~ 100,y取0,z取0。粒子運動是繞Y軸旋轉上升,同時在X、Y軸方向作微小的偏移,所以初始時,Y方向速度取0.5~1的隨機值,X、Z方向速度取-0.5~0.5的值。這里我們規定火焰的宣染範圍固定為200X200的一個虛擬視覺範圍。調節生命值的範圍可改變火焰的高度。 構造火星 如前面所說,火星是一個從中心向四周逐漸變暗的光點,程序中用了一個11X11的正方形表示。因為火焰效果是很多火星的疊加效果,所以中心亮度(最亮點)不能取最大值255。 宣染效果 依次將各火星的亮度疊加起來,將結果放到虛擬視屏緩衝里,等待畫到direct surface中。注意這里是對調色板的索引值進行計算,緩衝區中的結果也是索引值,因為索引值與亮度是成比例的。 效果不錯吧?其它一些特效如云、煙、霧等,都可利用此原理生成。你要做的就是將它消化、吸收,讓它為你所用。 源碼編譯需DX SDK6.1,DXGuide,VC 6.0。 注:程序僅為了說明原理,所以未做優化,且只在565顯卡上運行過,如速度不夠快或顏色不對請自行優化或修改程序中的調色板。 waterfall源碼 (11K) -------------------------------------------------------------------------------- 瀑布 瀑布用粒子系統來實現非常簡單,想象一下中學物理學過的拋物運動,一個乒乓球(OC天天放在口袋里的那種)在平滑的桌面受到一水平外力作用從桌面的一端滾下,從離開桌面的一刻起,乒乓球在水平方向作勻速運動,同時在垂直方向作勻加速運動,當乒乓球落到地面時還要發生彈性碰撞。這就是我們仿真瀑布所需要的。首先瀑布從高山上流下,然后在谷底濺起。同以往的粒子系統一樣,我們首先來構造需要的粒子:
#define PTCCNT 6096        struct PARTICLE {
    FLOAT x, y,
          tx, ty;
    BYTE  life;
}; 
PARTICLE ptcs[PTCCNT];
WORD pal[32];
BYTE buf[BUFW*BUFH];
粒子數 坐標 速度 生命值 粒子 調色板 視屏緩衝 景象首先是在一個視屏緩衝區(buf)中渲染好后再畫到back buffer里的,簡化起見,建立了一個從黑到藍的32色調色板,當然你可以構造更逼真的調色板來獲得更好的效果。
void InitPal() // 初始化調色板
{
    for (WORD I=0; I<32; I  )
        pal[I] = I | ((I>>1)<<5);
}    void InitPtc() // 初始化粒子
{
    for (int I=0; I     {
        // 起始位置(源頭)
        ptcs[I].x = 180;
        ptcs[I].y = 4;
        // 初始速度
        ptcs[I].tx = -(float)(32-(rand()%8))/64;
        ptcs[I].ty = (((float)rand())/(float)RAND_MAX) 0.25;
        ptcs[I].life = (BYTE)rand();
    }
}    void InitAll()
{
    InitPal();
    InitPtc();
    ZeroMemory(buf, BUFW*BUFH);
}    void ServeIt()
{
    ZeroMemory(buf, BUFW*BUFH);
    int nPtr;
    for (int I=0; I< PTCCNT; I  )
    {
        ptcs[I].life--;
        if (ptcs[I].life == 0)
        {
            ptcs[I].x = 180;
            ptcs[I].y = 4;
            ptcs[I].tx = -(float)(32-(rand()%8))/64;
            ptcs[I].ty = (((float)rand())/(float)RAND_MAX) 0.25;
        }
        ptcs[I].x  = ptcs[I].tx;
        ptcs[I].y  = ptcs[I].ty;
        if (ptcs[I].y > 197)
        {
            // 反彈
            ptcs[I].tx  = (5.0/64.0);
            ptcs[I].ty = -(((float)rand())/(float)RAND_MAX);
        }
        // 在緩衝畫點
        nPtr = ((int)ptcs[I].y)*BUFW   (int)ptcs[I].x;
        buf[nPtr] = ptcs[I].life / 8;
        // 垂直加速
        ptcs[I].ty  = 1.0/64.0;            // 如要好看,可對緩衝畫面作一些
        // 虛化工作
        // ……
    }
}    // 將緩衝畫面畫到back buffer
void RendIt(WORD* pwDest, WORD wDestPitch)
{
    int nPtr = 0;
    WORD *pwD1 = pwDest;
    WORD *pwD2;
    register WORD wCol;
    for(int I=0; I     {
        pwD2 = pwD1;
        for(int j=0; j         {
            wCol = pal[buf[nPtr]];
            if (wCol)
                *pwD2 = wCol;
            pwD2  ;
            nPtr  ;
        }
        pwD1 = (WORD*)((BYTE*)pwD1   wDestPitch);
    }
}
 
本文的例程編譯需VC6,DXSDK,DXGuide。 時間就是金錢---[ 發問前請先找找舊文章] 發表人 - axsoft 於 2002/08/14 17:07:39
系統時間:2024-04-26 15:14:15
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!