天天看點

Cocos2d-x C++ Sprite、Texture2D、TextureCache、SpriteBatchNode、SpriteFrame、SpriteFrameCache及相關類 源碼簡析SpriteTextureProtocolBlendProtocolTexture2DTextureCacheTextureAtlasSpriteBatchNodeSpriteFrameSpriteFrameCache相關OpenGL函數

文章目錄

  • Sprite
    • 簡介
      • 渲染模式
        • QUAD(預設模式)
        • POLYGON
        • SLICE9
        • QUAD_BATCHNODE
      • 優化渲染
    • 屬性介紹
      • 當節點由圖集渲染時使用以下屬性
        • _textureAtlas、_atlasIndex
        • _batchNode
      • 當節點由自身渲染時使用以下屬性
        • _blendFunc
        • _texture、_rect、_rectRotated
      • 當節點渲染模式為slice 9使用以下屬性
        • _centerRectNormalized
      • 以下為通用屬性
        • _renderMode
        • _stretchFactor、_stretchEnabled
        • _opacityModifyRGB
        • _flippedX、_flippedY
        • _insideBounds
        • _fileName、_fileType
        • _spriteFrame
        • _trianglesCommand
    • 函數介紹
      • void setTexture(Texture2D *texture)
      • void setSpriteFrame(SpriteFrame *spriteFrame)
      • void setDisplayFrameWithAnimationName(const string& animationName, ssize_t frameIndex)
  • TextureProtocol
  • BlendProtocol
    • 簡介
    • BlendFunc
      • DISABLE
      • ALPHA_PREMULTIPLIED
      • ALPHA_NON_PREMULTIPLIED
      • ADDITIVE
  • Texture2D
    • 簡介
    • 函數介紹
      • static void setDefaultAlphaPixelFormat(PixelFormat format)
      • void releaseGLTexture()
      • void setAliasTexParameters()
      • void setAntiAliasTexParameters()
    • PixelFormat
      • 簡介
      • BGRA8888、RGBA8888
      • RGB888
      • RGB565
      • A8
      • I8
      • AI88
      • RGBA4444
      • RGB5A1
      • PVRTC、ETC、ATITC
    • PixelFormatInfo
    • FontDefinition
  • TextureCache
    • 簡介
    • 屬性介紹
      • _loadingThread
      • _asyncStructQueue、_requestQueue、_responseQueue
      • _requestMutex、_responseMutex
      • _sleepCondition
      • _needQuit
      • _asyncRefCount
      • _textures
      • s_etc1AlphaFileSuffix
    • 函數介紹
      • void addImageAsync(const string &path, const function<void(Texture2D*)>& callback, const string& callbackKey)
      • void unbindImageAsync(const string& callbackKey)
      • void loadImage()
      • void addImageAsyncCallBack(float dt)
      • Texture2D* addImage(const string &path)
      • void parseNinePatchImage(Image *image, Texture2D *texture, const string& path)
      • bool reloadTexture(const string& fileName)
      • void removeAllTextures()
      • void reloadAllTextures()
      • void waitForQuit()
      • string getCachedTextureInfo() const
    • AsyncStruct
  • TextureAtlas
  • SpriteBatchNode
    • 簡介
    • 屬性介紹
      • DEFAULT_CAPACITY
      • _descendants
    • 函數介紹
      • static SpriteBatchNode* create(const string& fileImage, ssize_t capacity = DEFAULT_CAPACITY)
  • SpriteFrame
  • SpriteFrameCache
    • 簡介
    • PlistFramesCache
      • 簡介
      • 屬性介紹
        • _spriteFrames
        • _indexPlist2Frames
        • _indexFrame2plist
        • _isPlistFull
  • 相關OpenGL函數
    • glPixelStorei
    • glDeleteTextures
    • glGenTextures
    • glTexParameteri
    • glCompressedTexImage2D/glTexImage2D

Sprite

簡介

Sprite是一個顯示2D圖像的節點,可以根據圖檔、紋理、精靈幀(或其一部分矩形區域)建立。使用圖檔建立時,會先根據檔案名從TextureCache中查找紋理緩存,詳情參見TextureCache。

渲染模式

QUAD(預設模式)

渲染一個矩形區域(由兩個三角形構成),記憶體占用較小,但在圖檔未填滿矩形區域的情況下會渲染空像素(較慢)。

POLYGON

使用大量三角形區域(數量由設定決定)進行渲染,占用記憶體較多,但可以避免渲染大量的空像素(較快)。可以調用setPolygonInfo()更換到此模式。

SLICE9

将圖檔分為3*3的區域,渲染9個矩形區域(由18個三角形區域構成),中間的矩形區域可以進行拉伸,而其他8個區域保持不變,一般用于不定長圖形等。可以調用setCenterRect()或serCenterRectNormalized()更換到此模式。

SLICE9渲染模式的應用

QUAD_BATCHNODE

多個節點在一個批次中渲染的模式,但有許多限制,詳情參見SpriteBatchNode。将節點添加至SpriteBatchNode的子節點中即更換到此模式。

優化渲染

  1. 使用SpriteFrameCache中的圖集建立Sprite,詳情參見SpriteFrameCache。
  2. 多個Sprite盡量使用同一種顔色混合方式。

屬性介紹

當節點由圖集渲染時使用以下屬性

_textureAtlas、_atlasIndex

SpriteBatchNode所用的圖集及所用圖檔的實際下标(弱引用,不增加引用計數),詳情參見TextureAtlas。

_batchNode

此節點所屬的SpriteBatchNode節點(弱引用,不增加引用計數),詳情參見SpriteBatchNode。

當節點由自身渲染時使用以下屬性

_blendFunc

顔色混合方式,詳情參見TextureProtocol。

_texture、_rect、_rectRotated

節點使用的材質、所用的矩形範圍(預設為材質大小)以及矩形是否經過旋轉,詳情參見Texture2D。

當節點渲染模式為slice 9使用以下屬性

_centerRectNormalized

指定slice 9的中心區域的矩形。

以下為通用屬性

_renderMode

節點的渲染模式。

_stretchFactor、_stretchEnabled

節點的拉伸比例以及是否開啟拉伸(翻轉X/Y軸,設定大小等視為進行拉伸,Scale不視為拉伸)。QUAD模式需要通過此值計算偏移量,slice 9模式需要通過此值計算不同區域的矩形拉伸,Polygon和QUAD_BATCHNODE模式不使用此值。

_opacityModifyRGB

修改透明度是否會同步修改RGB數值。

_flippedX、_flippedY

是否沿X/Y軸翻轉。

_insideBounds

Sprite上一幀時是否在可視邊界内。

_fileName、_fileType

Sprite使用的紋理對應的圖檔名和類型。

_spriteFrame

Sprite使用的精靈幀。如果該Sprite不是由圖集建立的,則此值為nullptr,在調用getter時才會動态的根據Texture建立SpriteFrame并傳回(此節點不保持這個SpriteFrame的引用,如果值為nullptr每次調用getter都會傳回新的SpriteFrame),詳情參見SpriteFrame。

_trianglesCommand

存儲這個節點的渲染指令。

函數介紹

void setTexture(Texture2D *texture)

設定新紋理,同時會重置紋理區域到紋理的大小。如果将紋理置nullptr,不會使_texture變量變為nullptr而會使用一個2*2的白色預設圖檔取代。

void setSpriteFrame(SpriteFrame *spriteFrame)

設定新的精靈幀,如果紋理不同會同時更新紋理。

void setDisplayFrameWithAnimationName(const string& animationName, ssize_t frameIndex)

設定Sprite的SpriteFrame為從動畫幀中某一時刻的SpriteFrame。

TextureProtocol

BlendProtocol的子類,在定義了顔色混合方式的基礎上增加了對Texture的getter/setter。

BlendProtocol

簡介

OpenGL的顔色混合協定,存儲決定使用哪種顔色混合方式的變量。

BlendFunc

用來代表某種顔色混合方式的結構體,決定當節點渲染時對每個像素點如何進行顔色混合。src屬性代表源節點使用的混合方式,dst代表目标節點使用的混合方式,引擎給出了幾種常用的混合方式。詳情參見此處。

DISABLE

忽略目标點的RGBA,使用源點RGBA完全覆寫。

ALPHA_PREMULTIPLIED

目标點RGBA根據源點透明度進行修正,源點RGBA不變後進行疊加。

ALPHA_NON_PREMULTIPLIED

目标點RGBA根據源點透明度進行修正,源點RGBA同樣根據透明度修正後疊加。

ADDITIVE

目标點RGBA不變,源點RGBA根據自身透明度修正後疊加。

Texture2D

簡介

處理OpenGL中2D紋理的類,可以通過圖檔、文本、源資料快速建立紋理。紋理中的實際圖檔大小可能會小于紋理大小。

注意:生成的紋理資料是倒置的。

Texture2D不會被自動釋放(除了異步加載時),當不使用時需要手動調用release函數或使用TextureCache進行釋放。

函數介紹

static void setDefaultAlphaPixelFormat(PixelFormat format)

設定新建立Texture的預設像素格式。擁有透明度的圖檔将使用預設的像素格式,而不含透明度的圖檔在預設格式是RGBA8888的的情況下使用RGBA8888,其他預設格式則使用RGB565(是以圖檔應使用含透明度的格式,以確定在程式中的像素格式可以自己控制)。

這個函數不影響pvr/pvr.ccz格式的圖檔。

void releaseGLTexture()

僅釋放OpenGL中目前對應的紋理(不釋放目前對象)。

void setAliasTexParameters()

給紋理添加抗鋸齒。

void setAntiAliasTexParameters()

給紋理添加平滑過渡。

PixelFormat

簡介

Texture2D的像素格式枚舉。其中R代表紅色通道數值,G代表綠色通道數值,B代表藍色通道數值,A代表透明度通道數值。

BGRA8888、RGBA8888

RGBA通道數值各占8位,一個像素占4位元組,标準像素格式。

RGB888

去除了透明度通道的格式,一個像素占3位元組,對于不透明圖檔可以在保持畫質的情況下節省空間。去除了透明度通道僅代表圖檔沒有透明像素,而在引擎中仍然可以對其更改透明度(節點的透明度與紋理中像素的透明度無關)。

RGB565

R、B通道占5位,G通道占6位,一個像素占2位元組,以畫質為代價進一步節省了空間。

A8

顔色隻有黑色(無視圖像原本的顔色),隻有8位透明度通道的格式,一個像素占1位元組,通常用于蒙版遮罩。

I8

隻有亮度(黑白度)的格式,圖像為黑白色且沒用透明度通道,一個像素占1位元組。

AI88

亮度和透明度通道各占8位的格式,一個像素占2位元組,通常用于蒙版遮罩。

RGBA4444

RGBA通道數值各占4位,一個像素占2位元組,畫質損失最嚴重的格式。

RGB5A1

RGB通道數值各占5位,A通道占1位,一個像素占2位元組,适用于隻有全透明像素和非透明像素的圖檔。

PVRTC、ETC、ATITC

分别代表3種壓縮格式,其中pvrtc隻能用于ios,安卓官方規定格式是etc,attic是高通adreno系列GPU支援的格式。

PixelFormatInfo

與PixelFormat相對應的各像素格式的具體資訊。

FontDefinition

文字作為圖檔顯示時的一些參數定義。

TextureCache

簡介

TextureCache可以緩存加載過的紋理,節省加載重複紋理時的時間。但如果有不需要的紋理需要手動調用removeTexture函數進行釋放,否則會持續占用記憶體。

屬性介紹

_loadingThread

用于紋理異步加載的線程的引用。

_asyncStructQueue、_requestQueue、_responseQueue

用于異步加載紋理時存儲需要加載的資訊和結果的隊列。

_requestMutex、_responseMutex

用于異步加載紋理的線程鎖。

_sleepCondition

用于在需要異步加載紋理時喚醒加載線程。

_needQuit

是否正在等待結束遊戲。

_asyncRefCount

異步加載的紋理個數。

_textures

緩存的紋理,使用unordered_map存儲。

s_etc1AlphaFileSuffix

圖檔使用etc1壓縮時,透明度通道存儲的檔案的字尾。

函數介紹

void addImageAsync(const string &path, const function<void(Texture2D*)>& callback, const string& callbackKey)

異步加載紋理,加載完成後調用回調函數,callbackKey用于取消特定的異步加載回調。如果紋理已經加載将立刻調用回調函數。

加載步驟:

  1. 根據需要加載的資訊構造AsyncStruct結構體,加線程鎖後放入_requestQueue中,同時喚醒加載線程,為主線程添加定時器。
  2. 線程從_requestQueue中取出結構體,進行加載。
  3. 加載完成後加載線程加線程鎖後把紋理指針放入_responseQueue中,然後線程等待。
  4. 主線程中定時器每幀調用,判斷_responseQueue中是否有資料,如果有則進行處理并調用異步加載回調。
  5. 若異步加載隊列數量為0,則定時器會銷毀自身。

異步加載的Texture會被自動釋放。

void unbindImageAsync(const string& callbackKey)

取消執行指定異步加載的回調函數(指定的紋理仍會被加載,然後在加載的那幀結束時被自動釋放)。

void loadImage()

加載線程執行的函數。

void addImageAsyncCallBack(float dt)

主線程中定時執行用于檢測異步加載是否完成的函數。

Texture2D* addImage(const string &path)

在主線程中加載紋理,如果已在緩存中存在則直接傳回。

void parseNinePatchImage(Image *image, Texture2D *texture, const string& path)

判斷圖檔是否為9Patch圖檔,如果是則将紋理轉換為9Patch類型。

bool reloadTexture(const string& fileName)

從紋理中重新加載紋理,如果未加載過也會進行加載。

void removeAllTextures()

移除對所有紋理的引用(除非紋理隻有這一個引用,否則不會被釋放)。

void reloadAllTextures()

此函數内容為空,如果想重新加載所有紋理請手動周遊調用reloadTexture函數。

void waitForQuit()

在遊戲退出時被Director調用,用于等待加載線程結束。

string getCachedTextureInfo() const

傳回所有緩存的Texture的詳細資訊,一般用于調試時檢視記憶體占用。

AsyncStruct

記錄圖檔異步加載資訊的結構體,包括了傳回狀态、加載檔案名、加載回調函數等資訊。

TextureAtlas

TextureAtlas(紋理圖集)可以在運作時手動更新QUAD(每個Sprite後代對應一個QUAD),并使用VBO進行渲染,效率更高,詳情參見此處。

SpriteBatchNode

簡介

SpriteBatchNode用于批量繪制同一個紋理(即同一張Image、同一個TextureAtlas)的Sprite。次節點的所有後代的渲染模式為QUAD_BATCHNODE,會在一次OpenGL調用時全部繪制,消耗更少的性能。通常此節點與存儲在SpriteFrameCache中的圖集配合使用。此節點的Texture存儲在TextureAtlas中,渲染時隻使用SpriteBatchNode的TextureAtlas進行渲染以提升性能。

注意:此節點的所有後代都必須是Sprite且使用相同紋理,且所有節點共享抗鋸齒(Aliased)和平滑過渡(Antialiased)屬性,因為這些是屬于紋理的。

隻有添加了QUAD到TextureAtlas中的節點才會被繪制,添加節點而不添加QUAD、移除QUAD而不移除節點的節點都不會被繪制。

屬性介紹

DEFAULT_CAPACITY

TextureAtlas中QUAD、子節點和後代節點數組的預設大小,如果TextureAtlas中的QUAD數組容量不夠每次擴容1/3。

_descendants

該SpriteBatchNode的所有後代節點。

函數介紹

static SpriteBatchNode* create(const string& fileImage, ssize_t capacity = DEFAULT_CAPACITY)

根據圖檔名建立SpriteBatchNode,圖檔名為該節點樹下的節點必須所屬的圖檔名。

注意:如果使用圖集,則應傳入圖檔名而非plist字尾的名字,或者使用createWithTexture函數更友善。

SpriteFrame

記錄Sprite所使用的Texture、使用的區域、大小、錨點等,對于圖集來說非常重要(圖集中不同的區域代表了不同的圖檔)。當需要修改某個Sprite的圖檔時,應修改SpriteFrame而不是修改Texture。修改Texture會修改所有使用此紋理的Sprite(如果是圖集的話會修改所有使用此圖集的Sprite),而修改SpriteFrame隻會修改單個Sprite(除非你将這個Sprite作用于了多了Sprite)。

如果需要将圖檔修改成同一圖集中的其他圖檔,隻需要改變SpriteFrame所在Texture的區域即可。

SpriteFrameCache

簡介

存儲由圖集建立的精靈幀的緩存(自己建立的與直接用圖檔/材質建立的精靈幀不會緩存)。緩存具體由PlistFramesCache管理。由圖集建立的SpriteFrame應在不用時手動進行remove防止持續占用記憶體。

PlistFramesCache

簡介

通過Plist加載的SpriteFrame的緩存。

為什麼建議使用圖集?

屬性介紹

_spriteFrames

緩存中所有SpriteFrame名與引用的映射。

_indexPlist2Frames

緩存中plist名與對應的SpriteFrame名的集合的映射。

_indexFrame2plist

SpriteFrame名與對應的plist名的映射。

_isPlistFull

存儲對應的plist名是否加載。

相關OpenGL函數

glPixelStorei

設定OpenGL每次讀取的位元組數,如果設定不當導緻會導緻越界讀取進而導緻圖像錯誤、程式崩潰等。

glDeleteTextures

根據id删除OpenGL中對應的紋理。

glGenTextures

在OpenGL中生成紋理,并傳回紋理對應的id。

glTexParameteri

圖象從紋理映射到顯存時,需要使用這個函數來确定映射的方式。

glCompressedTexImage2D/glTexImage2D

将壓縮/未壓縮的紋理映射至緩存。

繼續閱讀