• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            劍孤寒的小站

            人生的價值不是用時間,而是用深度去衡量的!
            posts - 75, comments - 290, trackbacks - 0, articles - 0

            在現在的3D游戲中有很多非常漂亮的Shader特效,比如爆炸產生的氣浪,水流過玻璃使后面的景物變得扭曲等。這些特效并不是3D游戲的專利,有很多特效其實也是可以用在2D游戲里的,今天這一節我們就來學習一下如何在Galaxy2D游戲引擎中使用PixelShader制作爆炸氣浪效果。

            首先要判斷顯卡是否支持PixelShader,在OnInitiate()函數中添加:

            if (System_GetState(GGE_PSVERSION) < PS_2_0) return false;

            然后創建ShaderRenderTarget

            m_shaderFx = Shader_Load("shader.fx""ShaderFx", PS_2_0);
            m_fxTarget 
            = Texture_Create(640480true);
            m_targetTex 
            = Texture_Create(640480true);

            Shader_Load()函數用于載入Shader文件,第一個參數是Shader文件名,第二個參數指定Shader入口函數,第三個參數指定使用的Shader 版本,這里使用的是PS2.0

            RenderTarget就像一個臨時的畫布,我們可以將貼圖畫在某個RenderTarget上而不影響后臺緩存或其它的RenderTarget,常常用來做一些特殊效果,在這里m_fxTarget用于繪制NormalMap貼圖,m_targetTex用于繪制正常圖像,以便最后進行Shader合成。為了使用Shader還必須將m_shaderFx綁定到一個ggeSprite上:m_targetSpr->SetShader(m_shaderFx);

            接下來在OnUpdate(float dt)里添加如下代碼:

            if (Input_IsKeyDown(GGEK_SPACE))
            {
                   m_alpha.a 
            = 1;       //氣浪強度
                   m_posX = Random_Int(256384);//氣浪中心點位置
                   m_posY = Random_Int(176304); //氣浪中心點位置
                   m_scale = 1.0f;//氣浪大小
            }

            Input_IsKeyDown()函數用于判斷是否有鍵按下,后面的GGEK_SPACE是空格鍵的虛擬鍵值,其他的鍵值可在文檔里找到。在Galaxy2D引擎里提供了一系列Input_*函數,用于鍵盤鼠標輸入判斷。

            最后在OnRender()添加如下代碼:

             

            //如果alpha值大于0才進行Shader合成
                    if (m_alpha.a > 0)
                    
            {
                        
            //開始在m_fxTarget上畫東西
                        Graph_BeginScene(m_fxTarget);
                        Graph_Clear();
                        m_fxSpr
            ->SetColor(m_alpha.GetColor());
                        m_fxSpr
            ->SetPositionEx(m_posX, m_posY, 0, m_scale);
                        m_fxSpr
            ->Render();
                        Graph_EndScene();
                    }


                    
            //開始畫正常圖像
                    Graph_BeginScene(m_targetTex);
                    Graph_Clear(
            0);
                    m_bgSpr
            ->Render();
                    Graph_EndScene();

                    Graph_BeginScene();
                    
            if (m_alpha.a > 0)
                    
            {
                        
            //綁定Shader要使用的紋理
                        Graph_SetCurrentShader(m_shaderFx);
                        m_shaderFx
            ->SetTexture("FxTex", m_targetTex, true, TEXADDRESS_BORDER, 0);
                        m_shaderFx
            ->SetTexture("NormalMapTex", m_fxTarget);
                    }

                    
            else
                    
            {
                        Graph_SetCurrentShader(
            0);
                    }


                    m_targetSpr
            ->Render();
                    Graph_SetCurrentShader(
            0);
                    Graph_EndScene();

             好了,現在將下面的Shader代碼復制到shader.fx文件中就大功告成了:

            sampler2D FxTex:register(s0);
            sampler2D NormalMapTex:register(s1);

            float4 ShaderFx(float2 texCoord:TEXCOORD0):COLOR0
            {
                float3 normal 
            = tex2D(NormalMapTex, texCoord);
                texCoord 
            += dot(normal, float3(000.1));
                float4 tex 
            = tex2D(FxTex, texCoord);

                
            return tex;
            }


             

            最后上一張最終效果圖,由于gif只有256色所以不大清楚,不過大致的效果還是可以看出來的,自己覺得還是比較華麗的^_^,當然Shader能做的不僅如此,只要大家發揮想象力一定能作出更Cool更華麗的特效。

            Feedback

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2010-01-17 18:05 by Davy.xu
            問下,怎樣讓RenderTarget的紋理繪制帶alpha通道?

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2010-01-17 19:23 by 劍孤寒
            如果顯卡支持,
            Galaxy2D在創建RenderTarget時優先創建帶Alpha通道的紋理,
            可用Graph_Clear(0)將RenderTarget的Alpha通道清0并在上面繪制帶Alpha通道的紋理,
            但正如前面所說這項功能是依賴顯卡的,
            所以并不推薦使用。

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2012-03-03 23:49 by ljb
            實現原理還是改變坐標紋理

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效[未登錄]  回復  更多評論   

            2015-10-07 00:57 by shepherd
            由于種種原因,我準備自己封裝資源格式。但是這樣文件是直接讀入到內存的,音頻、紋理這些G2D是支持內存流直接讀取的;但是ini和xml有什么辦法直接讀取內存流嗎?要是自己寫語法分析器,就太累了

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2015-10-07 14:40 by 劍孤寒
            @shepherd
            xml可以用ggeXmlDocument::Parse()函數直接讀取內存中的數據,至于ini么,我不知道有了xml,還有啥用ini的理由,至少我已經5、6年沒用過這玩意了

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效[未登錄]  回復  更多評論   

            2015-10-08 01:20 by shepherd
            這是我根據提示修改的代碼。采用讀xml文件的LoadFile方法工作正常。采用加載到內存的Parse方法則失敗。是不是我用的不對啊?
            char buffer[256];
            long size = 0;
            FILE *fp = fopen(resource_name, "rb");
            fseek(fp, 0, SEEK_END);
            size = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            fread(buffer, size, 1, fp);
            fclose(fp);

            ggeXmlDocument *doc = Xml_Create();
            //打開xml文件
            doc->Parse(buffer);
            //doc->LoadFile(resource_name);
            //獲取根節點
            ggeXmlNode root = doc->GetRootNode();

            ggeXmlNode music = root.GetFirstChild("music");
            strcpy_s(name, 100, music.GetName());
            ggeXmlNode item = music.GetFirstChild("volume");
            hot_volume = atoi(item.GetFirstChild().GetName()); //得到volume
            item = music.GetFirstChild("count");
            int count = atoi(item.GetFirstChild().GetName()); //得到count

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2015-10-08 10:01 by 劍孤寒
            @shepherd
            呃,不知道你為啥不用Resource_Load()函數載入xml文件到內存,如果你非要用fopen的話,需要先把buffer清零,如果還不行的話,把xml文件內容貼一下我看看

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效[未登錄]  回復  更多評論   

            2015-10-08 12:49 by shepherd
            fopen那段就是測試用的,目的是把文件讀取到內存,用來測試內存讀取xml的效果。真正使用的時候,fopen那段時沒有的,函數直接接受一個void *buffer的指針,其內容來自自己的資源讀取函數。
            xml及相關代碼,發你郵箱吧。

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效  回復  更多評論   

            2015-10-09 09:59 by 劍孤寒
            @shepherd
            你那個buffer要清零啊

            char buffer[256];
            memset(buffer, 0, 256);<------加這個清零
            long size = 0;
            FILE *fp = fopen(resource_name, "rb");
            fseek(fp, 0, SEEK_END);
            size = ftell(fp);
            fseek(fp, 0, SEEK_SET);
            fread(buffer, size, 1, fp);
            fclose(fp);

            # re: Galaxy2D游戲引擎教程4 - 用PixelShader制作華麗的2D特效[未登錄]  回復  更多評論   

            2015-10-09 17:21 by shepherd
            根據提示,已經OK。正是這個原因,多謝!
            久久国产精品99精品国产| 久久综合九色综合欧美狠狠| 国产综合精品久久亚洲| 精品久久久久久久| 国产69精品久久久久99| 午夜视频久久久久一区 | 国产成人久久AV免费| 国产精品日韩欧美久久综合| 国产精品女同一区二区久久| 性做久久久久久久久浪潮| 精品久久久无码人妻中文字幕| 亚洲第一极品精品无码久久| 久久久精品2019免费观看| 国产精品欧美久久久久天天影视 | 少妇高潮惨叫久久久久久| 精品久久久久久久| 久久婷婷色香五月综合激情| 色婷婷综合久久久久中文一区二区 | 青青国产成人久久91网| 久久综合一区二区无码| 国产精品久久久久aaaa| 亚洲欧美日韩久久精品| 亚洲国产天堂久久综合网站| 久久亚洲日韩看片无码| 久久精品国产精品亚洲| 狠狠色丁香久久综合五月| 亚洲乱码精品久久久久..| 亚洲精品WWW久久久久久| 94久久国产乱子伦精品免费| 久久99精品久久久久久动态图 | 久久午夜免费视频| 久久WWW免费人成—看片| 精品精品国产自在久久高清| 热re99久久6国产精品免费| 无码国内精品久久综合88| 久久国产视屏| 韩国三级中文字幕hd久久精品 | avtt天堂网久久精品| 久久久免费精品re6| 久久超乳爆乳中文字幕| 久久久噜噜噜久久中文福利|