Skip to content

Commit c9ac7ba

Browse files
committed
Fixed projection flipping bug for Metal render textures.
1 parent ea3ba67 commit c9ac7ba

File tree

2 files changed

+37
-12
lines changed

2 files changed

+37
-12
lines changed

cocos2d/CCRenderTexture.m

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ -(id)initWithWidth:(int)width height:(int)height pixelFormat:(CCTexturePixelForm
135135
_pixelFormat = format;
136136
_depthStencilFormat = depthStencilFormat;
137137

138-
_projection = GLKMatrix4MakeOrtho(0.0f, width, 0.0f, height, -1024.0f, 1024.0f);
138+
self.projection = GLKMatrix4MakeOrtho(0.0f, width, 0.0f, height, -1024.0f, 1024.0f);
139139

140140
CCRenderTextureSprite *rtSprite = [CCRenderTextureSprite spriteWithTexture:[CCTexture none]];
141141
rtSprite.renderTexture = self;
@@ -229,6 +229,37 @@ -(CCTexture *)texture
229229
return super.texture;
230230
}
231231

232+
static GLKMatrix4
233+
FlipY(GLKMatrix4 projection)
234+
{
235+
return GLKMatrix4Multiply(GLKMatrix4MakeScale(1.0, -1.0, 1.0), projection);
236+
}
237+
238+
// Metal texture coordinates are inverted compared to GL so the projection must be flipped.
239+
-(GLKMatrix4)projection
240+
{
241+
#if __CC_METAL_SUPPORTED_AND_ENABLED
242+
if([CCConfiguration sharedConfiguration].graphicsAPI == CCGraphicsAPIMetal){
243+
return FlipY(_projection);
244+
} else
245+
#endif
246+
{
247+
return _projection;
248+
}
249+
}
250+
251+
-(void)setProjection:(GLKMatrix4)projection
252+
{
253+
#if __CC_METAL_SUPPORTED_AND_ENABLED
254+
if([CCConfiguration sharedConfiguration].graphicsAPI == CCGraphicsAPIMetal){
255+
_projection = FlipY(projection);
256+
} else
257+
#endif
258+
{
259+
_projection = projection;
260+
}
261+
}
262+
232263
-(CCRenderer *)begin
233264
{
234265
CCTexture *texture = self.texture;
@@ -237,17 +268,8 @@ -(CCRenderer *)begin
237268
texture = self.texture;
238269
}
239270

240-
GLKMatrix4 projection = _projection;
241-
242-
#if __CC_METAL_SUPPORTED_AND_ENABLED
243-
if([CCConfiguration sharedConfiguration].graphicsAPI == CCGraphicsAPIMetal){
244-
// Metal texture coordinates are inverted compared to GL.
245-
projection = GLKMatrix4Multiply(GLKMatrix4MakeScale(1.0, -1.0, 1.0), projection);
246-
}
247-
#endif
248-
249271
CCRenderer *renderer = [[CCDirector sharedDirector] rendererFromPool];
250-
[renderer prepareWithProjection:&projection framebuffer:_framebuffer];
272+
[renderer prepareWithProjection:&_projection framebuffer:_framebuffer];
251273

252274
_previousRenderer = [CCRenderer currentRenderer];
253275
[CCRenderer bindRenderer:renderer];
@@ -547,7 +569,7 @@ -(void) setContentSize:(CGSize)size
547569
// XXX Thayer says: I'm pretty sure this is broken since the supplied content size could
548570
// be normalized, in points, in UI points, etc. We should get the size in points then convert
549571
// to pixels and use that to make the ortho matrix.
550-
_projection = GLKMatrix4MakeOrtho(0.0f, size.width, 0.0f, size.height, -1024.0f, 1024.0f);
572+
self.projection = GLKMatrix4MakeOrtho(0.0f, size.width, 0.0f, size.height, -1024.0f, 1024.0f);
551573
_contentSizeChanged = YES;
552574
}
553575

cocos2d/CCRenderTexture_Private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
GLKVector4 _clearColor;
2323

2424
float _contentScale;
25+
26+
// Raw projection matrix used for rendering.
27+
// For metal will be flipped on the y-axis compared to the .projection property.
2528
GLKMatrix4 _projection;
2629

2730
CCSprite* _sprite;

0 commit comments

Comments
 (0)