Cocos2D’s класс CCRenderTexture покрыт тайнами. Часть этого, потому что у этого есть аура низкого уровня к этому, и наверняка потому что это просто работает по-другому чем большинство узлов Cocos2D. В этой обучающей программе Вы изучите все о CCRenderTexture и для чего Вы можете использовать это. In this tutorial you’ll learn all about CCRenderTexture and what you can use it for.

Проект демонстрационного примера CCRenderTexture будет вести Вас посредством основного использования CCRenderTexture с 6 примерами, включая взятие скриншота, рисование с Вашими пальцами и применением размытого изображения полного экрана.

В качестве награды я также добавил пример для CCMutableTexture2D (иначе CCTexture2DMutable), который показывает, как Вы можете установить пикселы в изменчивой структуре.

Как создать CCRenderTexture

Создание CCRenderTexture столь же легко как создающий любой другой CCNode. Вы только должны определить ширину структуры и высоту и установить положение отдавать структуры. Так как CCRenderTexture наследует CCNode, Вы можете тогда только добавить это как, ребенок: Since CCRenderTexture inherits from CCNode you can then just add it as child:

CCRenderTexture* rtx = [CCRenderTexture renderTextureWithWidth:256CCRenderTexture renderTextureWithWidth:256
                            height:256];;
rtx.position = CGPointMake (240, 160);240, 160);
[сам addChild:rtx z:0 tag:1];0 tag:1];

Размер структуры может быть любым размером, это не должна быть власть два. Конечно, устройство может создать структуру, которая является властью два, таким образом, то же самое предостережение применяется что касается любой структуры. Например, если размер структуры будет 130×260, то у внутренней структуры будет размер 256×512 – следующая более высокая двухмерная власть. Структура будет использовать больше памяти соответственно. For example, if the texture size is 130×260 the internal texture will have a size of 256×512 – the next higher power of two dimensions. The texture will use more memory accordingly.

Вы можете также определить дополнительный формат пиксела структуры

CCRenderTexture* rtx = [CCRenderTexture CCRenderTexture
    renderTextureWithWidth:200
            height:200
          pixelFormat:kCCTexture2DPixelFormat_RGBA4444];
rtx.position = CGPointMake (240, 160);240, 160);
[сам addChild:rtx z:0 tag:1];0 tag:1];

Следующее - список поддержанных форматов пиксела структуры. Наиболее особенно Вы не можете создать PVR, или 8-битовый отдают структуры, только несжатые 16-битовые и 32-битовые структуры. Попытка создать отдавать структуру с различным форматом пиксела чем они приводит к катастрофе. Attempting to create a render texture with a different pixel format than these leads to a crash.

kCCTexture2DPixelFormat_RGBA8888 //32-битовый: RGB на 888 битов, альфа на 8 битов
kCCTexture2DPixelFormat_RGBA4444 //16-битовый: RGB на 444 бита, альфа на 4 бита
kCCTexture2DPixelFormat_RGB5A1  //16-битовый: RGB на 555 битов, альфа на 1 бит
kCCTexture2DPixelFormat_RGB565  //16-битовый: RGB на 565 битов, никакая альфа

По умолчанию недавно созданный отдают структуру, полностью прозрачно, таким образом, Вы ничего не будете видеть. Самый легкий способ сделать что-то с отдавать структурой должно очистить всю структуру с цветом. В этом случае с абсолютно случайными ценностями между 0.0f к 1.0f: In this case with completely random values between 0.0f to 1.0f:

[rtx clear:CCRANDOM_0_1 ())
     g:CCRANDOM_0_1 ()
     b:CCRANDOM_0_1 ()
     a:CCRANDOM_0_1 ()];];

Вообразите!

Нет, фактически Вы не имеете к. Есть изображение в качестве примера со случайным ясным цветом направо. Только смотрите! ======>> Just look! ======>>


Как отдать узлы на CCRenderTexture

Очевидно, Вы будете хотеть сделать больше с Вашим отдавать структуру, как рисование узлов (эльфы, лейблы, эффекты частицы, и т.д.) на структуру. Рисунок на отдавать структуру может произойти в любом методе, он не должен быть сделан в методе ничьей. Но предоставление действительно должно произойти между звонками в отдавать структуру, начинают и заканчивают методы. But rendering does have to happen between the calls to the render texture’s begin and end methods.

Для начинаются есть также beginWithClear, который очищает всю структуру с однородным цветом и альфа-ценностью. Прояснение рекомендуется, если Вы не хотите caleidoscope эффекта. Любой CCNode может быть оттянут на структуру просто, посылая узел сообщение посещения, которое потянет это: Any CCNode can be drawn onto the texture simply by sending the node the visit message which will draw it:

[rtx beginWithClear:1 g:1 b:1 a:CCRANDOM_0_1 ()]; g:1 b:1 a:CCRANDOM_0_1()];

//пошлите "посещение" узлов, которые должны быть предоставлены
[посещение someNode];
  
[конец rtx];

Имейте в виду, что сообщение посещения тянет узел, не метод ничьей. Если у Вас есть узел, который делает таможенный рисунок в его методе ничьей, и Вы хотите отдать тот узел на отдавать структуру, Вы должны будете переместить кодекс рисунка от метода ничьей до метода посещения.

Давайте создадим и давайте потянем эльфа на отдавать структуру. Отметьте, что расточительно создать нового эльфа каждый раз, когда Вы тянете на отдавать структуру, в особенности если Вы часто обновляете отдавать структуру (несколько раз в секунду). В этом случае Вы хотели бы припрятать про запас узлы, которые Вы тянете. In that case you would want to cache the nodes you’re drawing.

[rtx beginWithClear:1 g:1 b:1 a:CCRANDOM_0_1 ()]; g:1 b:1 a:CCRANDOM_0_1()];

Символ CCSprite* = [CCSprite spriteWithFile:@ "Icon.png"];CCSprite spriteWithFile:@"Icon.png"];
//0,0 положения узла в левом нижнем углу rtx
//это сосредотачивает узел на отдавать структуре:
icon.position =
  CGPointMake (rtx.sprite.contentSize.width * rtx.sprite.anchorPoint.x, .width * rtx.sprite.anchorPoint.x,
        rtx.sprite.contentSize.height * rtx.sprite.anchorPoint.y); * rtx.sprite.anchorPoint.y);
//посещение отдаст эльфа
[посещение символа];
  
[конец rtx];

Есть несколько важных моментов, чтобы испортить этого. Во-первых, так как отдавать структура уже - ребенок нашей сцены, узлы, предоставленные на отдавать структуру, должны не обязательно быть детьми также. Вручную посылая узел метод посещения, это оттянуто на отдавать структуру. Обычно это происходит автоматически, если узел добавлен как ребенок к иерархии сцены. Не добавляя это, мы можем потянуть узел вручную на отдавать структуру, но это не будет оттянуто в любое время или больше нигде. By manually sending the node the visit method, it gets drawn onto the render texture. Normally this happens automatically if the node is added as a child to the scene hierarchy. By not adding it, we can draw the node manually onto the render texture but it won’t be drawn anytime or anywhere else.

Мы также использовали эльфа отдавать структуры. Собственность эльфа - эльф, которого отдавать структура добавляет к себе, чтобы показать структуру. Сама отдавать структура ведет себя как стандартный CCNode. Это означает, что contentSize отдавать структуры и anchorPoint будут 0,0 – так, если Вы должны использовать их, Вы должны будете взять их от эльфа отдавать структуры вместо этого. The render texture itself behaves like a standard CCNode. This means that the render texture’s contentSize and anchorPoint will be 0,0 – so if you need to make use of these you will have to take them from the render texture’s sprite instead.

Хождение дальше, Вы можете фактически послать сообщение посещения не раз в каждый узел. Тем путем Вы можете отдать того же самого эльфа с различными свойствами, как изменения в цвете, положение, вращение или фильтрование структуры:



//посещение отдаст эльфа, которого мы создали выше
[посещение символа];

//отдайте того же самого эльфа снова с различными свойствами
icon.color = ccc3 (255, 200, 100);255, 200, 100);
icon.rotation =-70;70;
icon.scale = 4;;
icon.position = CGPointMake (-45, 135);-45, 135);
  
//выключите фильтрование
[icon.texture setAliasTexParameters];;
//отдайте эльфа без фильтрования
[посещение символа];
//возвратите фильтрование на
[icon.texture setAntiAliasTexParameters];;

Вы можете даже использовать различные функции смеси для каждого узла, которого Вы посылаете посещение. У Рея Вендерлича есть пример для этого случая использования в его Маскирующей обучающей программе Эльфа.

Как потянуть материал OpenGL на CCRenderTexture

На этого легко ответить. Так же, как Вы посылаете сообщение посещения в узлы, Вы можете также назвать любые команды рисунка OpenGL промежуточный начинание и закончить методы отдавать структуры. Вот простой пример: Here’s a simple example:

[rtx beginWithClear:0.0f g:0.0f b:0.0f a:0.0f]; g:0.0f b:0.0f a:0.0f];

//пример привлечения регулярного OpenGL наполняет на отдавать структуру
glLineWidth (2);;
glColor4f (0.6f, 0.0f, 0.0f, 0.4f);, 0.0f, 0.4f);
CGSize winSize = [CCDirector sharedDirector].winSize;.winSize;

для (интервал i = 0; я <winSize.height; я + = 5) i = 0; i < winSize.height; i += 5)
{
  ccDrawLine (CGPointMake (0, i), CGPointMake (winSize.width, i));, i), CGPointMake(winSize.width, i));
}
    
glColor4f (1.0f, 0.0f, 0.0f, 0.5f);, 0.0f, 0.5f);
glLineWidth (4);;
ccDrawQuadBezier (CGPointZero, CGPointMake (winSize.width, 0), , 0),
    CGPointMake (winSize.width, winSize.height), 12);), 12);
ccDrawQuadBezier (CGPointZero, CGPointMake (0, winSize.height), , winSize.height),
    CGPointMake (winSize.width, winSize.height), 12);), 12);
glColor4f (1.0f, 1.0f, 1.0f, 1.0f);, 1.0f, 1.0f);
glLineWidth (1);;

[конец rtx];

Важно подчеркнуть, что Вы можете сделать это в любом методе, например каждая структура в методе обновления. Вы не вынуждены отдать команды OpenGL на CCRenderTexture в методе ничьей узла.

Направо Вы будете видеть результат этого кодекса. Только связка линий, более или менее. И так как это также часто спрашивают: да, Вы можете потянуть изогнутые линии с Cocos2D, используя или ccDrawCubicBezier или ccDrawQuadBezier. And since this is also often asked: yes, you can draw curved lines with Cocos2D using either ccDrawCubicBezier or ccDrawQuadBezier.

Как создать эльфов из CCRenderTexture

Вы можете создать один или более узлов CCSprite, которые используют структуру эльфа CCRenderTexture. Недавно созданные эльфы изменятся всякий раз, когда Вы обновляете отдавать структуру. Вы не должны создать новое, отдают структуру для каждого нового эльфа, и при этом Вы не должны создать нового эльфа всякий раз, когда Вы обновили отдавать структуру. Я видел это в паре примеров, и я полагаю, что часть из “плохой отдает исполнительную основу проблем” структуры от бесполезного восстановления сил, отдают структуры и эльфов, вместо того, чтобы снова использовать существующие. You do not need to create a new render texture for each new sprite, nor do you need to create a new sprite whenever you updated the render texture. I’ve seen this in a couple examples and I believe that some of the “bad render texture performance” issues stem from needlessly re-creating render textures and sprites, instead of re-using the existing ones.

Вот то, как Вы можете создать эльфа из CCRenderTexture:

//создайте отдельного эльфа, используя rendertexture
//эльф будет обновлен всякий раз, когда rendertexture содержание изменяется
CCSprite* rtxSprite = [CCSprite spriteWithTexture:rtx.sprite.texture];CCSprite spriteWithTexture:rtx.sprite.texture];

//так как структура перевернута, эльфом нужно щелкнуть:
rtxSprite.scaleY =-1;1;
[сам addChild:rtxSprite];;

Распространенное заблуждение - то, что CCRenderTexture происходит из CCTexture2D. Это не делает, поэтому Вы не можете создать эльфа из объекта CCRenderTexture. Вместо этого Вы должны будете использовать sprite.texture CCRenderTexture, чтобы создать нового эльфа. И так как отдавать структура перевернута, Вы должны щелкнуть недавно созданным эльфом, иначе это оттянуто вверх тормашками. Instead you will have to use the CCRenderTexture’s sprite.texture to create a new sprite. And since the render texture is upside down, you have to flip the newly created sprite, otherwise it is drawn upside down.

Чтобы сделать Вашу жизнь немного легче, вот, категория CCSprite, которая позволяет Вам создавать CCSprite непосредственно из CCRenderTexture. Этот кодекс находится также в демонстрационном проекте:

@interface CCSprite (RenderTextureCategory)
+ (id) spriteWithRenderTexture: (CCRenderTexture *) rtx; spriteWithRenderTexture:(CCRenderTexture*)rtx;
@end

@implementation CCSprite (RenderTextureCategory)
+ (id) spriteWithRenderTexture: (CCRenderTexture *) rtx spriteWithRenderTexture:(CCRenderTexture*)rtx
{
  Эльф CCSprite* = [CCSprite spriteWithTexture:rtx.sprite.texture];CCSprite spriteWithTexture:rtx.sprite.texture];
  sprite.scaleY =-1;1;
  возвратите эльфа;
}
@end

Если Вы создаете CCSprite из CCRenderTexture, Вы можете заметить, что CCRenderTexture предоставлен по-другому чем CCSprite использованием структуры отдавать структуры. Это - то, потому что режимы смешивания отличаются для эльфа CCRenderTexture и регулярных объектов CCSprite. Это вызовет CCRenderTexture (покинутый) быть предоставленным непрозрачное, тогда как у CCSprite (право) есть прозрачные области. This will cause the CCRenderTexture (left) to be rendered opaque, whereas the CCSprite (right) has transparent areas.

Как создать скриншоты с CCRenderTexture

Один из часто задаваемых вопросов, "как создать скриншот с Cocos2D?”. Различные решения были созданы в течение долгого времени, захватывая буфер структуры OpenGL например. Но действительно самое легкое и самое гибкое решение состоит в том, чтобы просто использовать CCRenderTexture, чтобы взять скриншот. Сильное преимущество CCRenderTexture состоит в том, что Вы можете пропустить определенные узлы, или только взять скриншот определенного слоя и его детей. Вы также не должны волноваться об экономии скриншота, так как CCRenderTexture имеет, может сделать это с его saveBuffer методами. Various solutions have been created over time, grabbing the OpenGL frame buffer for example. But truly the easiest and most flexible solution is to simply use a CCRenderTexture to take a screenshot. The powerful advantage of CCRenderTexture is that you can skip specific nodes, or only take a screenshot of a specific layer and its children. You also don’t need to worry about saving the screenshot, since CCRenderTexture has can do that with its saveBuffer methods.

Демонстрационный проект содержит класс CCScreenshot, который позволяет Вам брать скриншот, начинающийся с определенного узла. Это также обертывает раздражающую часть создания пути к папке документов приложения – единственное место, где Вы можете сохранить новые файлы на и устройство ИОСА:

+ (NSString *) screenshotPathForFile: (NSString *) файл) screenshotPathForFile:(NSString *)file
{
 Пути NSArray* = NSSearchPathForDirectoriesInDomains
   (NSDocumentDirectory, NSUserDomainMask, ДА);
 NSString* documentsDirectory = [пути objectAtIndex:0];paths objectAtIndex:0];
 NSString* screenshotPath = [documentsDirectory documentsDirectory
   stringByAppendingPathComponent:file];
 возвратите screenshotPath;
}

Взятие самого скриншота - мертво простой. Во-первых, CCRenderTexture с размером области экрана создан. Мы можем тогда только посетить узел, который передали к методу. saveBuffer метод тогда экономит скриншот. We can then just visit the node that was passed to the method. The saveBuffer method then saves the screenshot.

+ (CCRenderTexture *) screenshotWithStartNode: (CCNode *) startNode ) screenshotWithStartNode:(CCNode*)startNode
                  имя файла: (NSString *) имя файлаNSString*)filename
{
 [CCDirector sharedDirector].nextDeltaTimeZero = ДА; = YES;
  
 CGSize winSize = [CCDirector sharedDirector].winSize;.winSize;
 CCRenderTexture* rtx =
   [CCRenderTexture renderTextureWithWidth:winSize.width
                    height:winSize.height];;
 [rtx начинаются];
 [посещение startNode];
 [конец rtx];
  
 //сохраните как файл как PNG
 [rtx saveBuffer: [сам screenshotPathForFile:filename][self screenshotPathForFile:filename]
      format:kCCImageFormatPNG];
  
 возвратите rtx;
}

Это стоит упомянуть, что отдавать структура явно не очищена. Так как это недавно создано, отдают структуру, это уже очищено. Запрос, ясный снова, был бы расточителен. Calling clear again would be wasteful.

Формат saveBuffer явно собирается сохранить файл как PNG. Неплатеж saveBuffer метод без параметра формата не должен использоваться, так как это сохранит файл как JPG. Я объяснил в более раннем сообщении в блоге, почему JPGs - худший формат файла для устройств ИОСА: JPGs ужасно не спешат загружать. PNG - привилегированный формат. Для CCRenderTexture JPG и PNG - только два выбора формата. I’ve explained in an earlier blog post why JPGs are the worst possible file format for iOS devices: JPGs are terribly slow to load. PNG is the preferred format. For CCRenderTexture JPG and PNG are the only two format choices.

Скриншот отдает структуру, возвращен в случае, если Вы хотите немедленно создать CCSprite из отдавать структуры. Создание скриншота тогда столь же просто как звонящий screenshotWithStartNode с именем файла и соответствующим стартовым узлом, например сцена или только один из ее слоев:

[CCScreenshot screenshotWithStartNode:self filename:screenshotFile];screenshotFile];

Отметьте, что погрузка screenshot.png файла от диска медленнее чем создание нового CCSprite от уже существующей структуры. Но если Вы действительно загружаете файл скриншота, Вы должны удостовериться, что удалили его из CCTextureCache. Тайник структуры будет только видеть, что Вы пытаетесь загрузить то же самое имя файла снова. Если уже будет структура в памяти с тем именем файла, то обновленный screenshot.png не будет загружен даже при том, что его содержание изменилось. Позволить перезагружать screenshot.png звонок файла removeTextureForKey со всем путем к файлу скриншота: The texture cache will only see that you’re trying to load the same file name again. If there’s already a texture in memory with that filename, the updated screenshot.png will not be loaded even though its contents have changed. To allow reloading the screenshot.png file call removeTextureForKey with the full path to the screenshot file:

//получите весь путь к файлу скриншота
Файл NSString* = "screenshot.png";;
NSString* screenshotPath = [CCScreenshot screenshotPathForFile:file];CCScreenshot screenshotPathForFile:file];
    
//структура скриншота должна быть удалена из тайника структуры,
//вызвать перезагрузку нового от диска
[[CCTextureCache sharedTextureCache] removeTextureForKey:screenshotPath]; removeTextureForKey:screenshotPath];
    
//добавьте эльфа от недавно созданного скриншота
CCSprite* screenshotSprite = [CCSprite spriteWithFile:screenshotPath];CCSprite spriteWithFile:screenshotPath];

Заметьте, что после спасения CCRenderTexture с saveBuffer как PNG или файл JPG, Вы больше не должны щелкнуть (scaleY =-1) эльфом, когда Вы создаете новый из файла скриншота.

Скриншот к праву показывает недавно взятый скриншот, дистиллируемый фактическая сцена, и медленно исчезновение и переезжать.

Только не ожидайте создавать скриншот, или даже только размера экрана отдает структуру (не экономя) без значимой исполнительной задержки даже на последних устройствах. Это - определенно не что-то, что Вы будете хотеть сделать, в то время как Ваша игра начинается, но она прекрасно подходит, чтобы взять скриншот для savegame или после победы игры, например.

Рисование / Делающий набросок с CCRenderTexture

Этот зуд царапина и запечатлевает эскиз. Другими словами: как использовать CCRenderTexture для рисунка или рисования эскизов программы. Основное различие, здесь являющееся этим, Вы не хотите очищать отдавать структуру каждый раз, Вы начинаете тянуть к ней: how to use CCRenderTexture for a drawing or sketching program. The main difference here being that you do not want to clear the render texture every time you begin drawing to it:

//явно не очищайте rendertexture
[rtx начинаются];
международный цвет = 0;;
  
для (UITouch* затрагивают в прикосновениях), touch in touches)
{
  CGPoint touchLocation = [касаются locationInView:director.openGLView];director.openGLView];
  touchLocation = [директор convertToGL:touchLocation];touchLocation];

  //местоположение должно быть преобразовано в пространство узла rtx эльфа
  touchLocation = [rtx.sprite convertToNodeSpace:touchLocation]; convertToNodeSpace:touchLocation];

  //потому что эльфом щелкают вдоль его Оси Y,
  //координатой Y нужно также щелкнуть:
  touchLocation.y = rtx.sprite.contentSize.height - touchLocation.y;.contentSize.height - touchLocation.y;

  //установите щетку в том местоположении и отдайте это
  brush.position = touchLocation;
  [сам setBrushColor:color ++];];
  [почистите посещение];
}
  
[конец rtx];

Важный, чтобы рассмотреть факт, что местоположения прикосновения должны быть преобразованы в пространство узла эльфа отдавать структуры. Попытка преобразовать местоположение прикосновения в пространство узла отдавать структуры не будет давать Вам правильные результаты. Кроме того, так как структура эльфа перевернута, координата touchLocation.y должна также быть инвертирована так, чтобы происхождение (0, 0) координата была эффективно в левом верхнем углу структуры. Furthermore, since the sprite’s texture is upside down, the touchLocation.y coordinate must also be inverted so that the origin (0, 0) coordinate is effectively at the upper left corner of the texture.

Другое любопытство некоторым может быть то, как я в состоянии повторить по объектам UITouch. Это - обычная практика, чтобы "собрать" прикосновения во множестве или просто сохраняя NSSet. В этом случае я пошел со множеством. Каждое новое прикосновение добавлено ко множеству, и всякий раз, когда прикосновение заканчивается, это удалено: In this case I went with an array. Each new touch is added to the array, and whenever a touch ends it is removed:

- (BOOL) ccTouchBegan: (UITouch *), касаются withEvent: (UIEvent *) случай ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
  //добавьте новые прикосновения ко множеству, поскольку они входят
  [прикосновения addObject:touch];;
  возвратите ДА;
}

- (пустота) ccTouchEnded: (UITouch *), касаются withEvent: (UIEvent *) случай) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
  //должен удалить прикосновения, которые закончились или где отменено
  [прикосновения removeObject:touch];;
}

- (пустота) ccTouchCancelled: (UITouch *), касаются withEvent: (UIEvent *) случай) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
  [сам ccTouchEnded:touch withEvent:event];event];
}

Столько, сколько палец остается на экране, соответствующий объект UITouch* остается в памяти и только обновляет свои свойства. Повторяя по прикосновениям выстраивают, я могу потянуть узлы в местоположении каждого пальца, даже когда один или более пальцев не перемещаются. Это позволяет эльфа, который предоставлен с очень низким opacity, чтобы стать более непрозрачным дольше, Вы продолжаете касаться того же самого местоположения, начиная с предоставления того же самого эльфа многократно, не очищая отдавать структуру становится совокупной операцией. This allows the sprite that is rendered with very low opacity to become more opaque the longer you keep touching the same location, since rendering the same sprite multiple times without clearing the render texture becomes an additive operation.

У рисования эскизов с отдавать структурой есть один существенный недостаток: Вы не можете уничтожить. То, что оттянуто на структуру, остается навсегда. Вы не можете убрать новое, или любой, потянуть команды. Вы можете только очистить всю структуру и позволить пользователю начинаться. What is drawn onto the texture remains forever. You can not take away the most recent, or any, draw commands. You can only clear the entire texture and let the user start over.

Однако, Вы можете достигнуть некоторых прохладных результатов как замечено в скриншоте.

Размытое изображение Fullscreen с CCRenderTexture

Как только я смог отдать содержание экрана в отдельную структуру, у меня была идея осуществить использование эффекта размытого изображения CCRenderTexture. Принцип относительно прост:

  • Создайте многократный, отдают структуры
  • Отдайте текущий экран в “наименее недавно оттянутый, чтобы” отдать структуру
  • Потяните все отдают структуры с увеличением opacity в заказе от наименее недавно оттянутого к до того, который был только обновлен с содержанием экрана

Это создает эффект пятна, делая не что иное как добавить теневые изображения с увеличивающейся прозрачностью. Вы можете видеть заключительный эффект в скриншоте направо.

Первая задача состоит в том, чтобы создать отдавать структуры, по умолчанию 4. Больше и уровень структуры понижается слишком далеко, любой меньше и эффект, просто столь же объявленный, как я хотел бы, чтобы это было. Так как я хочу эффект пятна обычно отдавать с прозрачностью, я создаю CCSprite от каждого, отдают структуру и только добавляют новых эльфов к детскому списку сцены. Отдавать структуры сохранены во множестве вместо этого. Чтобы быть в состоянии получить соответствующий CCSprite от каждого отдают структуру, которую я также назначаю renderSprite на userData собственность отдавать структуры: Since I want the blur effect to render normally with transparency, I’m creating a CCSprite from each render texture and only add the new sprites to the scene’s children list. The render textures are retained in an array instead. To be able to get the corresponding CCSprite from each render texture I also assign the renderSprite to the render texture’s userData property:

CGSize winSize = [CCDirector sharedDirector].winSize;.winSize;
renderTextures = [NSMutableArray arrayWithCapacity:kRenderTextureCount];kRenderTextureCount];
renderTextures = [renderTextures сохраняют];;

для (интервал i = 0; я <kRenderTextureCount; я ++) i = 0; i < kRenderTextureCount; i++)
{
  CCRenderTexture* rtx = [CCRenderTexture CCRenderTexture
      renderTextureWithWidth:winSize.width
              height:winSize.height];;
  rtx.position = CGPointMake (winSize.width / 2, winSize.height / 2);winSize.width / 2, winSize.height / 2);
    
  CCSprite* renderSprite = [CCSprite spriteWithRenderTexture:rtx];CCSprite spriteWithRenderTexture:rtx];
  renderSprite.position = rtx.position;;
    
  [сам addChild:renderSprite z:100 + я];100 + i];
  rtx.userData = renderSprite;
  [renderTextures addObject:rtx];;
}

Теперь прибывает умная часть. Так как сцена должна быть оттянута только в отдавать структуру, и затем сцена должна потянуть себя из этих 4, отдают эльфов структуры, я решил переписать метод посещения и явно не называю выполнение высшего качества. Это позволяет мне брать под контроль то, что предоставлено где. That allows me to gain control over what is rendered where.

Сначала я начинаю, таща все запятнанные движением узлы (признак == 10) на в настоящее время отбираемый отдают структуру. Тогда я переупорядочиваю отдавать структуры от наименее недавно оттянутого к последний раз оттянутому с увеличением z заказ и увеличение opacity. В то же самое время звонок selectNextRenderTexture также гарантирует, что следующее посещение потянет к наименее недавно оттянутый, отдают структуру. At the same time the call to selectNextRenderTexture will also ensure that the next visit will draw to the least recently drawn render texture.

Наконец, я просто называю посещение на любом узле, у которого нет признака 10, чтобы отдать им. Это включает отдавать эльфов структуры плюс любые другие узлы как лейблы или кнопка "Назад".

- (недействительное) посещение) visit
{
 //вызовите ручной рисунок, не звоня, супер посещают...
 //[посещение высшего качества];

 //отдайте в следующий rendertexture
 CCRenderTexture* rtx = [renderTextures objectAtIndex:renderTextures objectAtIndex:
   currentRenderTextureIndex];
 [rtx beginWithClear:0 g:0 b:0 a:0]; g:0 b:0 a:0];

 Узел CCNode*;
 CCARRAY_FOREACH ([сам дети], узел), node)
 {
  если (node.tag == 10) == 10)
  {
   [посещение узла];
  }
 }

 [конец rtx];
  
 //переупорядочьте отдавать структуры так, чтобы
 //последний раз предоставленная структура оттянута последняя
 [сам selectNextRenderTexture];
 международный индекс = currentRenderTextureIndex;
 для (интервал i = 0; я <kRenderTextureCount; я ++) i = 0; i < kRenderTextureCount; i++)
 {
  CCRenderTexture* rtx =
    (CCRenderTexture *) [renderTextures objectAtIndex:index];[renderTextures objectAtIndex:index];
  CCSprite* renderSprite = (CCSprite *) rtx.userData;CCSprite*)rtx.userData;
  renderSprite.opacity = (255.0f / kRenderTextureCount) * (я + 1);255.0f / kRenderTextureCount) * (i + 1);
  [сам reorderChild:renderSprite z:100 + я];100 + i];
  [сам selectNextRenderTexture];
    
  индекс ++;
  если (индекс> = kRenderTextureCount) { kRenderTextureCount) {
   индекс = 0;
  }
 }
  
 //потяните любые остающиеся узлы
 CCARRAY_FOREACH ([сам дети], узел), node)
 {
  если (node.tag! = 10) != 10)
  {
   [посещение узла];
  }
 }
}

Я удалил фоновое изображение для этой демонстрации так, чтобы эффект размытого изображения был более примечательным. Так же, как примечательный однако понижение работы, например на iPod 4 приблизительно к 40 fps. Это вероятно из-за факта, что есть 4 fullscreen предоставляемые структуры. This is very likely because of the fact that there are 4 fullscreen textures being rendered.

Пример размытого изображения в демонстрационном проекте будет ездить на велосипеде каждые 20 секунд или от прояснения или от не прояснения отдавать структуры. В последнем случае Вы можете создать эффект подобный caleidoscope, как замечено в скриншоте направо.

Пикселы набора с CCTexture2DMutable иначе CCMutableTexture2D

Другой часто задаваемый вопрос: Как получить/установить пикселы структуры с Cocos2D?

Есть обычно используемый класс CCTexture2DMutable, плавающий, вокруг которого был первоначально отправлен здесь Лэм Хоэнг Памом. Есть множество версий, плавающих вокруг, но самый современный класс CCTexture2DMutable (manucorporat) здесь.

С этим Вы можете создать эльфа, который использует изменчивую структуру:

//калибруйте изменчивую структуру с блоком набора памяти к белому
CGSize texSize = CGSizeMake (128, 128);, 128);
международные байты = texSize.width * texSize.height * 4; * texSize.height * 4;
textureData = malloc (байты);bytes);
memset (textureData, INT32_MAX, байты);;

CCMutableTexture2D* tex = [[CCMutableTexture2D alloc] [CCMutableTexture2D alloc]
    initWithData:textureData
     pixelFormat:kCCTexture2DPixelFormat_RGBA8888
     pixelsWide:texSize.width
     pixelsHigh:texSize.height
     contentSize:texSize];
[автовыпуск tex];
    
//повредите фильтрование структуры (никакое сглаживание, ясные и свежие пикселы)
[tex setAliasTexParameters];
    
эльф = [CCSprite spriteWithTexture:tex];tex];

Вы можете тогда бросить структуру того эльфа к CCMutableTexture2D и назвать его setPixelAt метод, чтобы изменить цвет пиксела в данном местоположении. Когда Вы сделаны, обновляя изменчивую структуру, Вы также должны звонить, применяются так, чтобы изменения стали видимыми:

CCMutableTexture2D* tex = (CCMutableTexture2D *) sprite.texture;CCMutableTexture2D*)sprite.texture;

CGPoint randomPos = CGPointMake (rect.size.width * CCRANDOM_0_1 (), .width * CCRANDOM_0_1(),
                rect.size.height * CCRANDOM_0_1 ()); CCRANDOM_0_1());
ccColor4B красят = ccc4 (CCRANDOM_0_1 () * 255, CCRANDOM_0_1 () * 255,) * 255, CCRANDOM_0_1() * 255,
            CCRANDOM_0_1 () * 255, CCRANDOM_0_1 () * 255); 255, CCRANDOM_0_1() * 255);

[tex setPixelAt:randomPos rgba:color];color];
[tex применяются];

Получение пиксела сделано подобным способом с pixelAt:

ccColor4B красят = [tex pixelAt:randomPos];randomPos];

Демонстрационный проект тянет движущийся цвет к случайным пикселам в структуре. Структура расширена, и фильтрование структуры выключено так, чтобы пикселы были более легко видимы.

Изменчивый CCRenderTexture?

Из любопытства я сделал подклассификацию эксперимента CCRenderTexture и изменение init метода, таким образом, это будет использовать CCTexture2DMutable. В то время как это работало отлично над Тренажером, он терпит крах на фактических устройствах ИОСА. Таким образом, кажется, что Вы не можете жениться на CCRenderTexture и CCTexture2DMutable. So it seems you can not marry CCRenderTexture and CCTexture2DMutable.

Чтобы установить или изменить пикселы на CCRenderTexture, Вы можете использовать регулярные команды рисунка OpenGL, или использовать методы рисования удобства Cocos2D’s как ccDrawPoint.

Проект демонстрационного примера CCRenderTexture


Захватите это здесь. Этот проект также доступен на моем github складе где я принимаю весь iDevBlogADay исходный код. where I host all of the iDevBlogADay source code.

Кодекс является бесплатным использовать и изменить как вам нравится. Весь мой кодекс действует в соответствии с Лицензией Массачусетского технологического института, CCTexture2DMutable не имеет никакой ясно опознаваемой лицензии, но, как говорили, был годен к употреблению “так свободно, как Вы желаете”.

Как обычно, если у Вас есть какие-либо вопросы, не стесняются спрашивать! И если Вы наслаждались этой почтой, не забывают чирикать, как или плюс - один это, Спасибо!


Помогите мне помочь Вам!

Я провожу свое все время, придумывающее новые идеи, которые помогут Вам стать лучшим разработчиком приложения. Я очень наслаждаюсь процессом обучения, подталкиванием границ (мой и Ваш и та из технологии), имея свободу преследовать то, независимо от того, что находится на моем уме или Вашем к смело программе, что никто не запрограммировал прежде, и написать о том, что я изучил. Помогите мне помочь Вам, просматривая продукты в Изучении Магазина Cocos2D. Help me help you by browsing the products in the Learn Cocos2D Store.


Каждая продажа позволяет мне продолжать писать лучший кодекс, больше обучающих программ и полезных ответов!
Теговый с:    

7 Ответов на, "Как использовать CCRenderTexture для Размытого изображения, Скриншотов и Эскизов Рисунка”

  1. Эндрю говорит:

    Как это может использоваться?

    У меня есть эта идея в моей голове, пожалуйста, исправьте меня, где я неправ.

    Вообразите сложного эльфа сделанным из повторяющихся образцов помещенный, чтобы сделать это значащим, основа того образца - одно изображение, это повторено на всем протяжении этого.

    Я мог сохранить память в размере приложения включением только что маленькое изображение изображения структуры (скажем.png) и затем использовать кодекс, чтобы распределить это вокруг в действительном самолете, затем отдать это к CCRenderTexture и затем использовать тот CCRenderTexture в качестве эльфа?

    Или я думаю о CCRenderTexture полностью неправильно?

    • Да, Вы можете уменьшить свой размер приложения, добавляя только маленькое изображение, которое используется, чтобы отдать образец. Однако, Вы не нуждаетесь в отдавать структуре, чтобы отдать образец. Если Вы используете партию эльфа, Вы можете отдать тот образец от нескольких эльфов, используя то же самое изображение, и это будет столь быстро. Вы могли также использовать tilemap, чтобы создать тот образец. Наконец, есть параметр структуры GL_REPEAT, с которым Вы можете определить область (прямоугольник), по которому будет повторена единственная структура, я предполагаю, что это будет самым быстрым выбором. If you use a sprite batch you can render that pattern from several sprites using the same image and it’ll be just as fast. You could also use a tilemap to create that pattern. Finally, there’s the GL_REPEAT texture parameter with which you can define an area (rectangle) over which a single texture will be repeated, I suppose that will be the fastest option.

  2. Пол Ну и дела говорит:

    Привет Штеффен,

    Большая статья.

    Действительно ли возможно использовать эффекты как CCLens3D на эльфе в CCRenderTexture? Раз так, как?

    • Я не знаю, но я предположил бы, что, если действие линзы бежит на эльфе, просто звоня [посещение эльфа], чтобы отдать это должно также отдать эффект линзы в своем текущем состоянии.

      • Пол Ну и дела говорит:

        Тому, не кажется, когда Вы только пытаетесь отдать автономный CCRenderTexture, который Вы хотите экспортировать как фотография.

        • Пол Ну и дела говорит:

          Проблемой был CCGrid3D, ограничен использованием размера окна, так, когда Вы обращаетесь, CCLens3D к отдавать структуре говорят 2048 x 1536, который это обрезало. Подклассификация CCGrid3D и добавление initializer, который строит структуру к размеру изображения плюс отвержение 2-ых & трехмерных методов проектирования, чтобы работать с размером изображения а не размером окна, работали прекрасный …

  3. [...] KKScreenshot от Screenshots, Размытого изображения и Тянущий с почтой CCRenderTexture [...]

Оставьте Ответ