Procházet zdrojové kódy

[cocos2d-objc] More two color tinting work.

badlogic před 8 roky
rodič
revize
3ed9290c6f

+ 2 - 0
spine-c/spine-c/include/spine/extension.h

@@ -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));

+ 3 - 0
spine-c/spine-c/src/spine/extension.c

@@ -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);
 }
 }

+ 6 - 6
spine-cocos2d-objc/spine-cocos2d-objc.xcodeproj/project.pbxproj

@@ -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>"; };
-		76BF7E061E66ED9C00485998 /* TwoColorBatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TwoColorBatcher.h; path = src/spine/TwoColorBatcher.h; sourceTree = "<group>"; };
+		76BF7E051E66ED9C00485998 /* GLUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = GLUtils.c; path = src/spine/GLUtils.c; 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 */,
-				76BF7E061E66ED9C00485998 /* TwoColorBatcher.h */,
+				76BF7E051E66ED9C00485998 /* GLUtils.c */,
+				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 */,

+ 60 - 11
spine-cocos2d-objc/src/spine/TwoColorBatcher.c → spine-cocos2d-objc/src/spine/GLUtils.c

@@ -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>
 
 
@@ -52,6 +52,8 @@ attribute vec4 a_position;
 attribute vec4 a_color;
 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;
@@ -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;
 }
 }
 );
 );
 
 
@@ -76,19 +78,62 @@ const char* TWO_COLOR_TINT_FRAGMENT_SHADER = STRINGIFY(
 \n#ifdef GL_ES\n
 \n#ifdef GL_ES\n
 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) {
-	glDeleteProgram(batcher->shader->program);
-	glDeleteShader(batcher->shader->vertexShader);
-	glDeleteShader(batcher->shader->fragmentShader);
-	FREE(batcher->shader);
+void spDisposeTwoColorBatcher(spTwoColorBatcher* batcher) {
+	spShader_dispose(batcher->shader);
 	glDeleteBuffers(1, &batcher->vertexBufferHandle);
 	glDeleteBuffers(1, &batcher->vertexBufferHandle);
 	FREE(batcher->verticesBuffer);
 	FREE(batcher->verticesBuffer);
 	glDeleteBuffers(1, &batcher->indexBufferHandle);
 	glDeleteBuffers(1, &batcher->indexBufferHandle);

+ 35 - 7
spine-cocos2d-objc/src/spine/TwoColorBatcher.h → spine-cocos2d-objc/src/spine/GLUtils.h

@@ -28,8 +28,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  * POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#ifndef TwoColorBatcher_h
-#define TwoColorBatcher_h
+#ifndef GLUtils_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();
-void _spTwoColorBatcher_add(spTwoColorBatcher* batcher, spVertex* triangles, unsigned short* indices, uint32_t textureHandle, uint32_t srcBlend, uint32_t dstBlend);
-void _spTwoColorBatcher_flush(spTwoColorBatcher* batcher);
-void _spDisposeTwoColorBatcher(spTwoColorBatcher* batcher);
+spTwoColorBatcher* spTwoColorBatcher_create();
+void spTwoColorBatcher_add(spTwoColorBatcher* batcher, spMeshPart* meshPart);
+void spTwoColorBatcher_flush(spTwoColorBatcher* batcher);
+void spDisposeTwoColorBatcher(spTwoColorBatcher* batcher);
 
 
-#endif /* TwoColorBatcher_h */
+#endif /* GLUtils_h */

+ 2 - 2
spine-cocos2d-objc/src/spine/SkeletonRenderer.h

@@ -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;

+ 41 - 10
spine-cocos2d-objc/src/spine/SkeletonRenderer.m

@@ -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];
-				for (int i = 0; i * 2 < verticesCount; ++i) {
-					CCVertex vertex;
-					vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0);
-					vertex.color = GLKVector4Make(r, g, b, a);
-					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]);
+				if (!self.twoColorTint) {
+					CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
+					for (int i = 0; i * 2 < verticesCount; ++i) {
+						CCVertex vertex;
+						vertex.position = GLKVector4Make(_worldVertices[i * 2], _worldVertices[i * 2 + 1], 0.0, 1.0);
+						vertex.color = GLKVector4Make(r, g, b, a);
+						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]);
+					}
+				} else {
+					spMeshPart meshPart;
+					spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend);
+					
+					[renderer enqueueBlock:^{
+						
+					} globalSortOrder:0 debugLabel: nil threadSafe: false];
 				}
 				}
 			}
 			}
 		}
 		}