天天看点

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

将压缩/未压缩的纹理映射至缓存。

继续阅读