傳奇繪圖更換筆記:ZenGL 一些需要注意的事情

ZenGL 的顏色位序 爲文檔中說明爲 TEX_RGBA 但實際在Delphi 爲ABGR 這或許是因爲Opengl 的端序和Delphi 下不太一致。

fx _setColor 這個函數卻不是使用ABGR  而是實在的RGBA  導致我在將傳奇客戶端改爲Zengl 迷糊了很久。但是其實可以將其顏色位序設置爲GL_BGRA_EXT 這樣可以做到兼容DIB位圖。不過Zengl的OpenGLALL單元並沒有提供常亮聲明。最終我在GLScene的頭文件內找到了 

  // PixelFormat
  GL_RGB                            = $1907;
  GL_RGBA                           = $1908;
  GL_BGRA_EXT                       = $80E1;

將其聲明 試了有效,

而且Zengl提供的混合模式是在是少的可憐。Src_ColorAdd的特效也沒有內置 最後還是從HGE內抄過來用。


另外ZenGL並沒有提供黑白效果。 作者說要麼在加載紋理的時候將其設置爲 TEX_GRAYSCALE  要麼自己GetData SetData處理。

這可如何是好這樣當玩家死了 那我灰白界面不是繪製不出來了麼。。。

也罷 最終自己從網上扒到圖片黑白化的原理 自己實現之 。因爲GetData SetData 導致其效率明顯低了很多。

procedure TTexture.GrayScale;
var
  PP:PByteArray;
  PPixel : PCardinal;
  nLen:Integer;
  Pixel:Cardinal;
  R,G,B:Byte;
  I:integer;
begin
  tex_GetData(Surface,PP);
  PPixel := PCardinal(PP);
  nLen := GetRealHeight * GetRealWidth;
  {
灰度處理一般有三種算法:
1 最大值法:即新的顏色值R=G=B=Max(R,G,B),這種方法處理後的圖片看起來亮度值偏高。
2 平均值法:即新的顏色值R=G=B=(R+G+B)/3,這樣處理的圖片十分柔和
3 加權平均值法:即新的顏色值R=G=B=(R * Wr+G*Wg+B*Wb),一般由於人眼對不同顏色的敏感度不一樣,
所以三種顏色值的權重不一樣,一般來說綠色最高,紅色其次,藍色最低,最合理的取值分別爲Wr = 30%,Wg = 59%,Wb = 11%
}
  //這裏使用的是第3總算法
  for i := 0 to nLen - 1 do
  begin
    Pixel := PPixel^;
    R := Pixel and $FF;
    G := (Pixel shr 8) and $FF;
    B := (Pixel shr 16) and $FF;

    R := Trunc(R * 0.3);
    G := Trunc(G * 0.59);
    B := Trunc(G * 0.11);
    
    R:= (R + G + B);

    PPixel^ := $FF000000 or (R) or (R shl 8) or (R shl 16);
    Inc(PPixel);
  end; 
  
  tex_SetData(Surface,PP,0,0,GetRealWidth,Surface.Height);
  FreeMem(PP);


另外關於黑夜效果的實現:

傳奇原來的黑夜效果 我沒太仔細看。是類似掩碼的方式進行 對於不同的亮度有不同的掩碼數據 對座標的色彩進行運算。而且寫的是彙編 比較高深。

這裏我爲了實現這種光效 參考的是HGE內DynamicLight 的例子 將其移至到Zengl並且工作。

1.需要一張和屏幕紋理一樣大的 光效層。

2.將其Fill爲 ARGB(Light,Light,Light,Light) 這個light 是Byte分量的亮度。

3.使用一張光效遮罩


4。使用Src_ColorAdd混合模式  將其繪製在光效層上 

        srcBlend := GL_DST_ALPHA;
        dstBlend := GL_SRC_COLOR; 



5.使用Multiply 混合模式將光效會在目標層上。

        srcBlend := GL_ZERO;
        dstBlend := GL_SRC_COLOR

最終效果是這樣的:



最後對ZenGL做一些總結.

使用很方便 而且跨平臺 效率也還不錯  但是功能並不是太完善。比如 我需要獲得紋理某個像素點 的像素 這種功能並沒有實現 智能獲取渲染目標的某個點 並且這個函數在全屏下還有問題。 目前我使用的是GetData,但是GetData 一下要拷貝所有像素(效率低)。如果要優化只能自己去學習Opengl相關的API。封裝的不算很好。

而且像素格式 Zengl源碼內只實現了一種RGBA  雖然可以像我前面說的  改爲ARGB 以便兼容DIB 但是Zengl本身並沒有提供。

對Png圖片紋理載入未完善。 png的圖片對透明通道的載入 只支持8bit的 其他的一律不行。

最後:在實際折騰了半個月後 真新感覺  Opengl的優勢就是跨平臺,真心不如DX好用.

如果再讓我在ZenGL和Hge中選擇的話  如果是改傳奇繪圖 我會用HGE  如果搞新項目 我會用ZenGL 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章