[cocos2d-objc] More two color tinting work.

This commit is contained in:
badlogic 2017-03-14 13:14:23 +01:00
parent cc9fdf3f1f
commit 3ed9290c6f
7 changed files with 149 additions and 36 deletions

View File

@ -64,6 +64,7 @@
/* All allocation uses these. */ /* All allocation uses these. */
#define MALLOC(TYPE,COUNT) ((TYPE*)_malloc(sizeof(TYPE) * (COUNT), __FILE__, __LINE__)) #define MALLOC(TYPE,COUNT) ((TYPE*)_malloc(sizeof(TYPE) * (COUNT), __FILE__, __LINE__))
#define CALLOC(TYPE,COUNT) ((TYPE*)_calloc(COUNT, sizeof(TYPE), __FILE__, __LINE__)) #define CALLOC(TYPE,COUNT) ((TYPE*)_calloc(COUNT, sizeof(TYPE), __FILE__, __LINE__))
#define REALLOC(PTR,TYPE,COUNT) ((TYPE*)_realloc(PTR, sizeof(TYPE) * (COUNT)))
#define NEW(TYPE) CALLOC(TYPE,1) #define NEW(TYPE) CALLOC(TYPE,1)
/* Gets the direct super class. Type safe. */ /* Gets the direct super class. Type safe. */
@ -162,6 +163,7 @@ char* _spUtil_readFile (const char* path, int* length);
void* _malloc (size_t size, const char* file, int line); void* _malloc (size_t size, const char* file, int line);
void* _calloc (size_t num, size_t size, const char* file, int line); void* _calloc (size_t num, size_t size, const char* file, int line);
void* _realloc(void* ptr, size_t size);
void _free (void* ptr); void _free (void* ptr);
void _setMalloc (void* (*_malloc) (size_t size)); void _setMalloc (void* (*_malloc) (size_t size));

View File

@ -46,6 +46,9 @@ void* _calloc (size_t num, size_t size, const char* file, int line) {
if (ptr) memset(ptr, 0, num * size); if (ptr) memset(ptr, 0, num * size);
return ptr; return ptr;
} }
void* _realloc(void* ptr, size_t size) {
return realloc(ptr, size);
}
void _free (void* ptr) { void _free (void* ptr) {
freeFunc(ptr); freeFunc(ptr);
} }

View File

@ -33,7 +33,7 @@
652107961895250000B1FF07 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 652107951895250000B1FF07 /* CoreText.framework */; }; 652107961895250000B1FF07 /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 652107951895250000B1FF07 /* CoreText.framework */; };
765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF41D7D7A08003FB779 /* goblins.atlas */; }; 765A2EF61D7D7A08003FB779 /* goblins.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF41D7D7A08003FB779 /* goblins.atlas */; };
765A2EF71D7D7A08003FB779 /* goblins.png in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF51D7D7A08003FB779 /* goblins.png */; }; 765A2EF71D7D7A08003FB779 /* goblins.png in Resources */ = {isa = PBXBuildFile; fileRef = 765A2EF51D7D7A08003FB779 /* goblins.png */; };
76BF7E071E66ED9C00485998 /* TwoColorBatcher.c in Sources */ = {isa = PBXBuildFile; fileRef = 76BF7E051E66ED9C00485998 /* TwoColorBatcher.c */; }; 76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = 76BF7E051E66ED9C00485998 /* GLUtils.c */; };
76F28D161DEC810300CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF41DEC810200CDE54D /* Animation.c */; }; 76F28D161DEC810300CDE54D /* Animation.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF41DEC810200CDE54D /* Animation.c */; };
76F28D171DEC810300CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF51DEC810300CDE54D /* AnimationState.c */; }; 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF51DEC810300CDE54D /* AnimationState.c */; };
76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF61DEC810300CDE54D /* AnimationStateData.c */; }; 76F28D181DEC810300CDE54D /* AnimationStateData.c in Sources */ = {isa = PBXBuildFile; fileRef = 76F28CF61DEC810300CDE54D /* AnimationStateData.c */; };
@ -160,8 +160,8 @@
652107951895250000B1FF07 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 652107951895250000B1FF07 /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
765A2EF41D7D7A08003FB779 /* goblins.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = goblins.atlas; path = Resources/goblins.atlas; sourceTree = "<group>"; }; 765A2EF41D7D7A08003FB779 /* goblins.atlas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = goblins.atlas; path = Resources/goblins.atlas; sourceTree = "<group>"; };
765A2EF51D7D7A08003FB779 /* goblins.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goblins.png; path = Resources/goblins.png; sourceTree = "<group>"; }; 765A2EF51D7D7A08003FB779 /* goblins.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = goblins.png; path = Resources/goblins.png; sourceTree = "<group>"; };
76BF7E051E66ED9C00485998 /* TwoColorBatcher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = TwoColorBatcher.c; path = src/spine/TwoColorBatcher.c; sourceTree = "<group>"; }; 76BF7E051E66ED9C00485998 /* GLUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GLUtils.c; path = src/spine/GLUtils.c; sourceTree = "<group>"; };
76BF7E061E66ED9C00485998 /* TwoColorBatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TwoColorBatcher.h; path = src/spine/TwoColorBatcher.h; sourceTree = "<group>"; }; 76BF7E061E66ED9C00485998 /* GLUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GLUtils.h; path = src/spine/GLUtils.h; sourceTree = "<group>"; };
76F28CF41DEC810200CDE54D /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../spine-c/spine-c/src/spine/Animation.c"; sourceTree = "<group>"; }; 76F28CF41DEC810200CDE54D /* Animation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Animation.c; path = "../spine-c/spine-c/src/spine/Animation.c"; sourceTree = "<group>"; };
76F28CF51DEC810300CDE54D /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../spine-c/spine-c/src/spine/AnimationState.c"; sourceTree = "<group>"; }; 76F28CF51DEC810300CDE54D /* AnimationState.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationState.c; path = "../spine-c/spine-c/src/spine/AnimationState.c"; sourceTree = "<group>"; };
76F28CF61DEC810300CDE54D /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../spine-c/spine-c/src/spine/AnimationStateData.c"; sourceTree = "<group>"; }; 76F28CF61DEC810300CDE54D /* AnimationStateData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = AnimationStateData.c; path = "../spine-c/spine-c/src/spine/AnimationStateData.c"; sourceTree = "<group>"; };
@ -329,8 +329,8 @@
43F7FF861927F94800CA4038 /* SkeletonRenderer.m */, 43F7FF861927F94800CA4038 /* SkeletonRenderer.m */,
43C3282E170B0C19004A9460 /* spine-cocos2d-objc.h */, 43C3282E170B0C19004A9460 /* spine-cocos2d-objc.h */,
43C3282D170B0C19004A9460 /* spine-cocos2d-objc.m */, 43C3282D170B0C19004A9460 /* spine-cocos2d-objc.m */,
76BF7E051E66ED9C00485998 /* TwoColorBatcher.c */, 76BF7E051E66ED9C00485998 /* GLUtils.c */,
76BF7E061E66ED9C00485998 /* TwoColorBatcher.h */, 76BF7E061E66ED9C00485998 /* GLUtils.h */,
); );
name = "spine-cocos2d-objc"; name = "spine-cocos2d-objc";
sourceTree = "<group>"; sourceTree = "<group>";
@ -562,7 +562,7 @@
76F28D171DEC810300CDE54D /* AnimationState.c in Sources */, 76F28D171DEC810300CDE54D /* AnimationState.c in Sources */,
76F28D221DEC810300CDE54D /* extension.c in Sources */, 76F28D221DEC810300CDE54D /* extension.c in Sources */,
76F28D231DEC810300CDE54D /* IkConstraint.c in Sources */, 76F28D231DEC810300CDE54D /* IkConstraint.c in Sources */,
76BF7E071E66ED9C00485998 /* TwoColorBatcher.c in Sources */, 76BF7E071E66ED9C00485998 /* GLUtils.c in Sources */,
43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */, 43C3282F170B0C19004A9460 /* spine-cocos2d-objc.m in Sources */,
76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */, 76F28D1F1DEC810300CDE54D /* BoundingBoxAttachment.c in Sources */,
76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */, 76F28D281DEC810300CDE54D /* PathConstraint.c in Sources */,

View File

@ -28,7 +28,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
#include "TwoColorBatcher.h" #include "GLUtils.h"
#include <spine/extension.h> #include <spine/extension.h>
@ -53,6 +53,8 @@ attribute vec4 a_color;
attribute vec4 a_color2; attribute vec4 a_color2;
attribute vec2 a_texCoords; attribute vec2 a_texCoords;
uniform mat4 transform;
\n#ifdef GL_ES\n \n#ifdef GL_ES\n
varying lowp vec4 v_light; varying lowp vec4 v_light;
varying lowp vec4 v_dark; varying lowp vec4 v_dark;
@ -68,7 +70,7 @@ void main() {
v_light = a_color; v_light = a_color;
v_dark = a_color2; v_dark = a_color2;
v_texCoord = a_texCoords; v_texCoord = a_texCoords;
gl_Position = CC_PMatrix * a_position; gl_Position = transform * a_position;
} }
); );
@ -77,18 +79,61 @@ const char* TWO_COLOR_TINT_FRAGMENT_SHADER = STRINGIFY(
precision lowp float; precision lowp float;
\n#endif\n \n#endif\n
uniform sampler2D texture;
varying vec4 v_light; varying vec4 v_light;
varying vec4 v_dark; varying vec4 v_dark;
varying vec2 v_texCoord; varying vec2 v_texCoord;
void main() { void main() {
vec4 texColor = texture2D(CC_Texture0, v_texCoord); vec4 texColor = texture2D(texture, v_texCoord);
float alpha = texColor.a * v_light.a; float alpha = texColor.a * v_light.a;
gl_FragColor.a = alpha; gl_FragColor.a = alpha;
gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb; gl_FragColor.rgb = (1.0 - texColor.rgb) * v_dark.rgb * alpha + texColor.rgb * v_light.rgb;
} }
); );
spMesh* spMesh_create(uint32_t numVertices, uint32_t numIndices) {
spMesh* mesh = MALLOC(spMesh, 1);
mesh->vertices = MALLOC(spVertex, numVertices);
mesh->indices = MALLOC(unsigned short, numIndices);
mesh->numVertices = numVertices;
mesh->numIndices = numIndices;
mesh->numAllocatedVertices = 0;
mesh->numAllocatedIndices = 0;
return mesh;
}
void spMesh_allocatePart(spMesh* mesh, spMeshPart* part, uint32_t numVertices, uint32_t numIndices, uint32_t textureHandle, uint32_t srcBlend, uint32_t dstBlend) {
if (mesh->numVertices < mesh->numAllocatedVertices + numVertices) {
mesh->numVertices = mesh->numAllocatedVertices + numVertices;
mesh->vertices = REALLOC(mesh->vertices, spVertex, mesh->numVertices);
}
if (mesh->numIndices < mesh->numAllocatedIndices + numIndices) {
mesh->numIndices = mesh->numAllocatedIndices + numIndices;
mesh->indices = REALLOC(mesh->indices, unsigned short, mesh->numIndices);
}
part->mesh = mesh;
part->startVertex = mesh->numAllocatedVertices;
part->numIndices = numIndices;
part->startIndex = mesh->numAllocatedIndices;
part->numVertices = numVertices;
mesh->numAllocatedVertices += numVertices;
mesh->numAllocatedIndices += numIndices;
}
void spMesh_clearParts(spMesh* mesh) {
mesh->numAllocatedIndices = 0;
mesh->numAllocatedVertices = 0;
}
void spMesh_dispose(spMesh* mesh) {
FREE(mesh->vertices);
FREE(mesh->indices);
FREE(mesh);
}
GLuint compileShader(GLenum shaderType, const char* shaderSource) { GLuint compileShader(GLenum shaderType, const char* shaderSource) {
GLuint shader = glCreateShader(shaderType); GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSource, 0); glShaderSource(shader, 1, &shaderSource, 0);
@ -134,7 +179,14 @@ spShader* spShader_create(const char* vertexShaderSource, const char* fragmentSh
return shader; return shader;
} }
spTwoColorBatcher* _spTwoColorBatcher_create() { void spShader_dispose(spShader* shader) {
glDeleteProgram(shader->program);
glDeleteShader(shader->vertexShader);
glDeleteShader(shader->fragmentShader);
FREE(shader);
}
spTwoColorBatcher* spTwoColorBatcher_create() {
spTwoColorBatcher* batcher = MALLOC(spTwoColorBatcher, 1); spTwoColorBatcher* batcher = MALLOC(spTwoColorBatcher, 1);
batcher->shader = spShader_create(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER); batcher->shader = spShader_create(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
@ -152,19 +204,16 @@ spTwoColorBatcher* _spTwoColorBatcher_create() {
return batcher; return batcher;
} }
void _spTwoColorBatcher_add(spTwoColorBatcher* batcher, spVertex* triangles, unsigned short* indices, uint32_t textureHandle, uint32_t srcBlend, uint32_t dstBlend) { void spTwoColorBatcher_add(spTwoColorBatcher* batcher, spMeshPart* mesh) {
} }
void _spTwoColorBatcher_flush(spTwoColorBatcher* batcher) { void spTwoColorBatcher_flush(spTwoColorBatcher* batcher) {
} }
void _spDisposeTwoColorBatcher(spTwoColorBatcher* batcher) { void spDisposeTwoColorBatcher(spTwoColorBatcher* batcher) {
glDeleteProgram(batcher->shader->program); spShader_dispose(batcher->shader);
glDeleteShader(batcher->shader->vertexShader);
glDeleteShader(batcher->shader->fragmentShader);
FREE(batcher->shader);
glDeleteBuffers(1, &batcher->vertexBufferHandle); glDeleteBuffers(1, &batcher->vertexBufferHandle);
FREE(batcher->verticesBuffer); FREE(batcher->verticesBuffer);
glDeleteBuffers(1, &batcher->indexBufferHandle); glDeleteBuffers(1, &batcher->indexBufferHandle);

View File

@ -28,8 +28,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
#ifndef TwoColorBatcher_h #ifndef GLUtils_h
#define TwoColorBatcher_h #define GLUtils_h
#include <stdint.h> #include <stdint.h>
@ -40,12 +40,40 @@ typedef struct spVertex {
float u, v; float u, v;
} spVertex; } spVertex;
typedef struct spMesh {
spVertex* vertices;
uint32_t numVertices;
uint32_t numAllocatedVertices;
unsigned short* indices;
uint32_t numIndices;
uint32_t numAllocatedIndices;
} spMesh;
typedef struct spMeshPart {
spMesh* mesh;
uint32_t startVertex;
uint32_t numVertices;
uint32_t startIndex;
uint32_t numIndices;
uint32_t textureHandle;
uint32_t srcBlend;
uint32_t dstBlend;
} spMeshPart;
spMesh* spMesh_create(uint32_t numVertices, uint32_t numIndices);
void spMesh_allocatePart(spMesh* mesh, spMeshPart* part, uint32_t numVertices, uint32_t numIndices, uint32_t textureHandle, uint32_t srcBlend, uint32_t dstBlend);
void spMesh_clearParts(spMesh* mesh);
void spMesh_dispose(spMesh* mesh);
typedef struct spShader { typedef struct spShader {
uint32_t program; uint32_t program;
uint32_t vertexShader; uint32_t vertexShader;
uint32_t fragmentShader; uint32_t fragmentShader;
} spShader; } spShader;
spShader* spShader_create(const char* vertexShaderSource, const char* fragmentShaderSource);
void spShader_dispose(spShader* shader);
typedef struct spTwoColorBatcher { typedef struct spTwoColorBatcher {
spShader* shader; spShader* shader;
@ -63,9 +91,9 @@ typedef struct spTwoColorBatcher {
int32_t texCoordsAttributeLocation; int32_t texCoordsAttributeLocation;
} spTwoColorBatcher; } spTwoColorBatcher;
spTwoColorBatcher* _spTwoColorBatcher_create(); spTwoColorBatcher* spTwoColorBatcher_create();
void _spTwoColorBatcher_add(spTwoColorBatcher* batcher, spVertex* triangles, unsigned short* indices, uint32_t textureHandle, uint32_t srcBlend, uint32_t dstBlend); void spTwoColorBatcher_add(spTwoColorBatcher* batcher, spMeshPart* meshPart);
void _spTwoColorBatcher_flush(spTwoColorBatcher* batcher); void spTwoColorBatcher_flush(spTwoColorBatcher* batcher);
void _spDisposeTwoColorBatcher(spTwoColorBatcher* batcher); void spDisposeTwoColorBatcher(spTwoColorBatcher* batcher);
#endif /* TwoColorBatcher_h */ #endif /* GLUtils_h */

View File

@ -29,7 +29,6 @@
*****************************************************************************/ *****************************************************************************/
#import <spine/spine.h> #import <spine/spine.h>
#import "TwoColorBatcher.h"
#import "cocos2d.h" #import "cocos2d.h"
/** Draws a skeleton. */ /** Draws a skeleton. */
@ -39,6 +38,7 @@
bool _debugSlots; bool _debugSlots;
bool _debugBones; bool _debugBones;
bool _premultipliedAlpha; bool _premultipliedAlpha;
bool _twoColorTint;
bool _skipVisibilityCheck; bool _skipVisibilityCheck;
ccBlendFunc _blendFunc; ccBlendFunc _blendFunc;
CCDrawNode* _drawNode; CCDrawNode* _drawNode;
@ -46,7 +46,6 @@
spAtlas* _atlas; spAtlas* _atlas;
float* _worldVertices; float* _worldVertices;
CCBlendMode* screenMode; CCBlendMode* screenMode;
spTwoColorBatcher* batcher;
} }
+ (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData; + (id) skeletonWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@ -85,6 +84,7 @@
- (bool) setAttachment:(NSString*)slotName attachmentName:(NSString*)attachmentName; - (bool) setAttachment:(NSString*)slotName attachmentName:(NSString*)attachmentName;
@property (nonatomic, readonly) spSkeleton* skeleton; @property (nonatomic, readonly) spSkeleton* skeleton;
@property (nonatomic) bool twoColorTint;
@property (nonatomic) bool debugSlots; @property (nonatomic) bool debugSlots;
@property (nonatomic) bool debugBones; @property (nonatomic) bool debugBones;
@property (nonatomic) bool skipVisibilityCheck; @property (nonatomic) bool skipVisibilityCheck;

View File

@ -31,9 +31,12 @@
#import <spine/SkeletonRenderer.h> #import <spine/SkeletonRenderer.h>
#import <spine/spine-cocos2d-objc.h> #import <spine/spine-cocos2d-objc.h>
#import <spine/extension.h> #import <spine/extension.h>
#import <spine/GLUtils.h>
#import "CCDrawNode.h" #import "CCDrawNode.h"
static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0}; static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
static spTwoColorBatcher* batcher = 0;
static spMesh* mesh = 0;
@interface SkeletonRenderer (Private) @interface SkeletonRenderer (Private)
- (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData; - (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData;
@ -43,6 +46,7 @@ static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
@synthesize skeleton = _skeleton; @synthesize skeleton = _skeleton;
@synthesize rootBone = _rootBone; @synthesize rootBone = _rootBone;
@synthesize twoColorTint = _twoColorTint;
@synthesize debugSlots = _debugSlots; @synthesize debugSlots = _debugSlots;
@synthesize debugBones = _debugBones; @synthesize debugBones = _debugBones;
@ -59,6 +63,14 @@ static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
} }
- (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData { - (void) initialize:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
if (!batcher) {
batcher = spTwoColorBatcher_create();
mesh = spMesh_create(64000, 32000);
[[CCDirector sharedDirector] addFrameCompletionHandler: ^{
printf ("frame completed");
}];
}
_ownsSkeletonData = ownsSkeletonData; _ownsSkeletonData = ownsSkeletonData;
_worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh. _worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
@ -154,6 +166,8 @@ static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
_skeleton->color.a = self.displayedOpacity; _skeleton->color.a = self.displayedOpacity;
int blendMode = -1; int blendMode = -1;
uint32_t srcBlend = GL_SRC_ALPHA;
uint32_t dstBlend = GL_ONE_MINUS_SRC_ALPHA;
const float* uvs = 0; const float* uvs = 0;
int verticesCount = 0; int verticesCount = 0;
const unsigned short* triangles = 0; const unsigned short* triangles = 0;
@ -200,15 +214,23 @@ static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
switch (slot->data->blendMode) { switch (slot->data->blendMode) {
case SP_BLEND_MODE_ADDITIVE: case SP_BLEND_MODE_ADDITIVE:
[self setBlendMode:[CCBlendMode addMode]]; [self setBlendMode:[CCBlendMode addMode]];
srcBlend = !_premultipliedAlpha ? GL_SRC_ALPHA : GL_ONE;
dstBlend = GL_ONE;
break; break;
case SP_BLEND_MODE_MULTIPLY: case SP_BLEND_MODE_MULTIPLY:
[self setBlendMode:[CCBlendMode multiplyMode]]; [self setBlendMode:[CCBlendMode multiplyMode]];
srcBlend = GL_DST_COLOR;
dstBlend = GL_ONE_MINUS_SRC_ALPHA;
break; break;
case SP_BLEND_MODE_SCREEN: case SP_BLEND_MODE_SCREEN:
[self setBlendMode:screenMode]; [self setBlendMode:screenMode];
srcBlend = GL_ONE;
dstBlend = GL_ONE_MINUS_SRC_COLOR;
break; break;
default: default:
[self setBlendMode:_premultipliedAlpha ? [CCBlendMode premultipliedAlphaMode] : [CCBlendMode alphaMode]]; [self setBlendMode:_premultipliedAlpha ? [CCBlendMode premultipliedAlphaMode] : [CCBlendMode alphaMode]];
srcBlend = !_premultipliedAlpha ? GL_SRC_ALPHA : GL_ONE;
dstBlend = GL_ONE_MINUS_SRC_ALPHA;
} }
} }
if (_premultipliedAlpha) { if (_premultipliedAlpha) {
@ -227,16 +249,25 @@ static const unsigned short quadTriangles[6] = {0, 1, 2, 2, 3, 0};
GLKVector2 center = GLKVector2Make(size.width / 2.0, size.height / 2.0); GLKVector2 center = GLKVector2Make(size.width / 2.0, size.height / 2.0);
GLKVector2 extents = GLKVector2Make(size.width / 2.0, size.height / 2.0); GLKVector2 extents = GLKVector2Make(size.width / 2.0, size.height / 2.0);
if (_skipVisibilityCheck || CCRenderCheckVisbility(transform, center, extents)) { if (_skipVisibilityCheck || CCRenderCheckVisbility(transform, center, extents)) {
CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0]; if (!self.twoColorTint) {
for (int i = 0; i * 2 < verticesCount; ++i) { CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
CCVertex vertex; for (int i = 0; i * 2 < verticesCount; ++i) {
vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0); CCVertex vertex;
vertex.color = GLKVector4Make(r, g, b, a); vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0);
vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]); vertex.color = GLKVector4Make(r, g, b, a);
CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform)); vertex.texCoord1 = GLKVector2Make(uvs[i * 2], 1 - uvs[i * 2 + 1]);
} CCRenderBufferSetVertex(buffer, i, CCVertexApplyTransform(vertex, transform));
for (int j = 0; j * 3 < trianglesCount; ++j) { }
CCRenderBufferSetTriangle(buffer, j, triangles[j * 3], triangles[j * 3 + 1], triangles[j * 3 + 2]); for (int j = 0; j * 3 < trianglesCount; ++j) {
CCRenderBufferSetTriangle(buffer, j, triangles[j * 3], triangles[j * 3 + 1], triangles[j * 3 + 2]);
}
} else {
spMeshPart meshPart;
spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend);
[renderer enqueueBlock:^{
} globalSortOrder:0 debugLabel: nil threadSafe: false];
} }
} }
} }