Cocos2D’s clase de CCRenderTexture es cubierto de misterios. La parte de ello porque esto tiene una aura baja a ello, y el más seguramente porque esto simplemente trabaja diferentemente que la mayor parte de nodos Cocos2D. En este seminario usted aprenderá todos sobre CCRenderTexture y para qué usted puede usarlo. In this tutorial you’ll learn all about CCRenderTexture and what you can use it for.

El proyecto de demostración de CCRenderTexture le dirigirá a través de usos básicos de CCRenderTexture con 6 ejemplos, incluso toma de un screenshot, dibujo con sus dedos y aplicación del aspecto borroso de movimiento de pantalla completa.

Como prima también he añadido un ejemplo para CCMutableTexture2D (aka CCTexture2DMutable) que muestra como usted puede poner pixeles en una textura mudable.

Como crear CCRenderTexture

La creación de CCRenderTexture es tan fácil como creando cualquier otro CCNode. Usted sólo tiene que especificar la anchura de la textura y la altura y poner la posición de la textura dar. Ya que CCRenderTexture hereda de CCNode usted puede añadirlo sólo entonces como el niño: 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);
[mí addChild:rtx z:0 tag:1];0 tag:1];

La talla de textura puede ser cualquier talla, no tiene que ser el poder de dos. Por supuesto, el dispositivo puede crear una textura que es el poder de dos, entonces la misma precaución se aplica en cuanto a cualquier textura. Por ejemplo, si la talla de textura es 130×260 la textura interna tendrá una talla de 256×512 – el siguiente poder más alto de dos dimensiones. La textura usará más memoria en consecuencia. 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.

Usted también puede especificar un formato de pixel de textura opcional

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

Lo siguiente es una lista de formatos de pixel de textura apoyados. El más notablemente usted no puede crear PVR o de 8 bites dan texturas, sólo las texturas de 16 bites y de 32 bites no comprimidas. El intento de crear una textura dar con un formato de pixel diferente que éstos lleva a un accidente. Attempting to create a render texture with a different pixel format than these leads to a crash.

kCCTexture2DPixelFormat_RGBA8888 //de 32 bites: RGB de 888 trozos, alfa de 8 trozos
kCCTexture2DPixelFormat_RGBA4444 //de 16 bites: RGB de 444 trozos, alfa de 4 trozos
kCCTexture2DPixelFormat_RGB5A1  //de 16 bites: RGB de 555 trozos, alfa de 1 trozo
kCCTexture2DPixelFormat_RGB565  //de 16 bites: RGB de 565 trozos, ninguna alfa

En ausencia recién creado dan la textura es totalmente transparente, entonces usted no verá nada. La manera más fácil de hacer algo con la textura dar debe limpiar la textura entera con un color. En este caso con valores completamente arbitrarios entre 0.0f a 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 ()];];

¡Imagine!

No, realmente usted no tiene a. Hay una imagen de ejemplo con un color claro arbitrario a la derecha. ¡Sólo mire! ======>> Just look! ======>>


Como dar nodos en CCRenderTexture

Obviamente usted querrá hacer más con su dar la textura, como el dibujo de nodos (elfos, etiquetas, efectos de partícula, etc.) en la textura. El dibujo en una textura dar puede pasar en cualquier método, no tiene que ser hecho en el método de empate. Pero la interpretación realmente tiene que pasar entre las llamadas a la textura dar comienzan y terminan métodos. But rendering does have to happen between the calls to the render texture’s begin and end methods.

Para comienzan también hay beginWithClear que limpia la textura entera con un color uniforme y valor alfa. El limpiado es recomendado a menos que usted quiera un efecto caleidoscope. Cualquier CCNode puede ser dibujado en la textura simplemente enviando el nodo el mensaje de visita que lo dibujará: 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()];

//envíe "la visita" a los nodos que deberían ser dados
[visita de someNode];
  
[final de rtx];

Tenga presente que el mensaje de visita dibuja el nodo, no el método de empate. Si usted tiene un nodo que hace el dibujo de encargo en su método de empate, y usted quiere dar aquel nodo en una textura dar, usted tendrá que mover el código de dibujo del método de empate al método de visita.

Vaya a crear y dibujar un elfo en la textura dar. Note que es pródigo crear un nuevo elfo cada vez usted dibuja en una textura dar, en particular si usted actualiza la textura dar a menudo (varias veces por segundo). En este caso usted querría esconder los nodos que usted dibuja. 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()];

Icono de CCSprite* = [CCSprite spriteWithFile:@ "Icon.png"];CCSprite spriteWithFile:@"Icon.png"];
//la 0,0 posición del nodo está en la esquina inferior e izquierda de rtx
//esto centra el nodo en la textura dar:
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);
//la visita dará el elfo
[visita de icono];
  
[final de rtx];

Hay varios puntos importantes para llevarse de esto. En primer lugar, ya que la textura dar es ya un niño de nuestra escena, los nodos dados en la textura dar no necesariamente tienen que ser niños también. Enviando a mano el nodo el método de visita, es dibujado en la textura dar. Normalmente esto pasa automáticamente si el nodo es añadido como un niño a la jerarquía de escena. No añadiéndolo, podemos dibujar el nodo a mano en la textura dar pero no será dibujado en cualquier momento o en ninguna otra parte. 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.

También hicimos el uso del elfo de la textura dar. La propiedad de elfo es el elfo que la textura dar añade a sí para mostrar la textura. La textura dar sí mismo se comporta como CCNode estándar. Esto significa que contentSize de la textura dar y anchorPoint serán 0,0 – tan si usted tiene que hacer el uso de éstos usted tendrá que tomarlos del elfo de la textura dar en cambio. 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.

Circular, usted realmente puede enviar el mensaje de visita más que una vez a cada nodo. Así usted puede dar el mismo elfo con propiedades diferentes, como cambios en color, posición, rotación o filtración de textura:



//la visita dará el elfo que creamos encima
[visita de icono];

//dé el mismo elfo otra vez, con propiedades diferentes
icon.color = ccc3 (255, 200, 100);255, 200, 100);
icon.rotation =-70;70;
icon.scale = 4;;
icon.position = CGPointMake (-45, 135);-45, 135);
  
//apague la filtración
[icon.texture setAliasTexParameters];;
//dé el elfo sin la filtración
[visita de icono];
//vuelva la filtración en
[icon.texture setAntiAliasTexParameters];;

Usted puede usar hasta funciones de mezcla diferentes para cada nodo al cual usted envía la visita. Ray Wenderlich tiene un ejemplo para este caso de uso en su seminario de Enmascaramiento de Elfo.

Como dibujar la materia de OpenGL en CCRenderTexture

Éste es fácil a contestar. Como usted envía el mensaje de visita a nodos, usted también puede llamar cualquier orden de dibujo de OpenGL entre comenzar y terminar métodos de la textura dar. Aquí está un ejemplo simple: 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];

//ejemplo de dibujar materia de OpenGL regular en la textura dar
glLineWidth (2);;
glColor4f (0.6f, 0.0f, 0.0f, 0.4f);, 0.0f, 0.4f);
CGSize winSize = [CCDirector sharedDirector].winSize;.winSize;

para (intervalo i = 0; yo <winSize.height; yo + = 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);;

[final de rtx];

Es importante subrayar que usted puede hacer esto en cualquier método, por ejemplo cada marco en el método de actualización. Usted no es obligado a dar órdenes de OpenGL en CCRenderTexture dentro del método de empate de un nodo.

A la derecha usted verá el resultado de este código. Sólo un manojo de líneas, más o menos. Y ya que también a menudo preguntan a esto: sí, usted puede dibujar líneas encorvadas con Cocos2D usando ccDrawCubicBezier o ccDrawQuadBezier. And since this is also often asked: yes, you can draw curved lines with Cocos2D using either ccDrawCubicBezier or ccDrawQuadBezier.

Como crear elfos de CCRenderTexture

Usted puede crear uno o varios nodos CCSprite que usan la textura de elfo de CCRenderTexture. Los elfos recién creados cambiarán siempre que usted actualice la textura dar. Usted no tiene que crear un nuevo dan la textura para cada nuevo elfo, tampoco usted tiene que crear un nuevo elfo siempre que usted actualizara la textura dar. He visto esto en unos ejemplos de pareja y creo que algunos del "malo dan el tallo de cuestiones” de rendimiento de textura de recrear innecesariamente dan texturas y elfos, en vez de reutilizar los existentes. 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.

Aquí está como usted puede crear un elfo de CCRenderTexture:

//cree un elfo separado usando el rendertexture
//el elfo será actualizado siempre que los contenido rendertexture cambien
CCSprite* rtxSprite = [CCSprite spriteWithTexture:rtx.sprite.texture];CCSprite spriteWithTexture:rtx.sprite.texture];

//ya que la textura es al revés, el elfo tiene que ser tirado:
rtxSprite.scaleY =-1;1;
[mí addChild:rtxSprite];;

Un error común es que CCRenderTexture se deriva de CCTexture2D. Esto no hace, por lo tanto usted no puede crear un elfo de un objeto de CCRenderTexture. En cambio usted tendrá que usar sprite.texture de CCRenderTexture para crear un nuevo elfo. Y ya que la textura dar es al revés, usted tiene que tirar el elfo recién creado, por otra parte es dibujado al revés. 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.

Para hacer su vida un poco más fácil, aquí está una categoría CCSprite que permite que usted cree un CCSprite directamente de CCRenderTexture. Este código también está en el proyecto de demostración:

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

@implementation CCSprite (RenderTextureCategory)
+ (id) spriteWithRenderTexture: (CCRenderTexture *) rtx spriteWithRenderTexture:(CCRenderTexture*)rtx
{
  Elfo de CCSprite* = [CCSprite spriteWithTexture:rtx.sprite.texture];CCSprite spriteWithTexture:rtx.sprite.texture];
  sprite.scaleY =-1;1;
  devuelva el elfo;
}
@end

Si usted crea un CCSprite de CCRenderTexture, usted puede notar que CCRenderTexture es dado diferentemente que el CCSprite la utilización de la textura de la textura dar. Esto es porque los modos de mezcla son diferentes para elfo de CCRenderTexture y objetos de CCSprite regulares. Esto causará CCRenderTexture (abandonado) ser dado opaco, mientras que el CCSprite (derecho) tiene áreas transparentes. This will cause the CCRenderTexture (left) to be rendered opaque, whereas the CCSprite (right) has transparent areas.

Como crear screenshots con CCRenderTexture

Una de las preguntas con frecuencia hechas es “¿cómo crear un screenshot con Cocos2D?”. Varias soluciones han sido creadas con el tiempo, agarrando el parachoques de marco de OpenGL por ejemplo. Pero realmente la solución más fácil y más flexible es usar simplemente CCRenderTexture para tomar un screenshot. La ventaja potente de CCRenderTexture consiste en que usted puede saltar nodos específicos, o sólo tomar un screenshot de una capa específica y sus niños. Usted también no tiene que preocuparse del ahorro del screenshot, ya que CCRenderTexture tiene puede hacer esto con sus métodos 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.

El proyecto de demostración contiene una clase CCScreenshot que permite que usted tome un screenshot que comienza con un nodo específico. Esto también envuelve el trozo molesto de crear un camino a la carpeta de documentos del app – el único lugar donde usted puede salvar nuevos archivos sobre y dispositivo iOS:

+ (NSString *) screenshotPathForFile: (NSString *) archivo) screenshotPathForFile:(NSString *)file
{
 Caminos de NSArray* = NSSearchPathForDirectoriesInDomains
   (NSDocumentDirectory, NSUserDomainMask, SÍ);
 NSString* documentsDirectory = [caminos objectAtIndex:0];paths objectAtIndex:0];
 NSString* screenshotPath = [documentsDirectory documentsDirectory
   stringByAppendingPathComponent:file];
 devuelva screenshotPath;
}

La toma del screenshot sí mismo está muerta simple. En primer lugar, CCRenderTexture con la talla del área de pantalla es creado. Podemos visitar sólo entonces el nodo que fue pasado al método. El método saveBuffer entonces salva el screenshot. 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
                  nombre del archivo: (NSString *) nombre del archivoNSString*)filename
{
 [CCDirector sharedDirector].nextDeltaTimeZero =; = YES;
  
 CGSize winSize = [CCDirector sharedDirector].winSize;.winSize;
 CCRenderTexture* rtx =
   [CCRenderTexture renderTextureWithWidth:winSize.width
                    height:winSize.height];;
 [los rtx comienzan];
 [visita de startNode];
 [final de rtx];
  
 //guarde como el archivo como PNG
 [rtx saveBuffer: [mí screenshotPathForFile:filename][self screenshotPathForFile:filename]
      format:kCCImageFormatPNG];
  
 devuelva rtx;
}

Esto vale la pena mencionar que la textura dar no es explícitamente limpiada. Ya que es un recién creado dan la textura, es limpiado ya. La vocación clara otra vez sería pródiga. Calling clear again would be wasteful.

El formato de saveBuffer es explícitamente hecho guardar el archivo como PNG. La falta saveBuffer método sin el parámetro de formato no debería ser usada, ya que esto guardará el archivo como JPG. He explicado en una entrada de bitácora más temprana por qué JPGs son el formato del archivo peor posible para dispositivos iOS: JPGs son terriblemente lentos para cargar. PNG es el formato preferido. Para CCRenderTexture JPG y PNG son las sólo dos opciones de formato. 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.

Los screenshot dan la textura es devuelto por si usted quiera crear inmediatamente un CCSprite de la textura dar. La creación del screenshot es tan simple entonces como llamando screenshotWithStartNode con un nombre de fichero y el nodo inicial apropiado, por ejemplo la escena o sólo una de sus capas:

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

Note que la carga del archivo screenshot.png del disco es más lenta que la creación de nuevo CCSprite de una textura ya existente. Pero si usted realmente carga el archivo screenshot, usted debería asegurarse para quitarlo de CCTextureCache. El escondite de textura sólo verá que usted trata de cargar el mismo nombre de fichero otra vez. Si hay ya una textura en la memoria con aquel nombre del archivo, screenshot.png actualizado no será cargado aunque sus contenido hayan cambiado. Permitir recargar la llamada de archivo screenshot.png removeTextureForKey con el camino entero al archivo screenshot: 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:

//consiga el camino entero al archivo screenshot
Archivo de NSString* = "screenshot.png";;
NSString* screenshotPath = [CCScreenshot screenshotPathForFile:file];CCScreenshot screenshotPathForFile:file];
    
//la textura screenshot debe ser quitada del escondite de textura,
//forzar recargo del nuevo de disco
[[CCTextureCache sharedTextureCache] removeTextureForKey:screenshotPath]; removeTextureForKey:screenshotPath];
    
//añada el elfo de screenshot recién creado
CCSprite* screenshotSprite = [CCSprite spriteWithFile:screenshotPath];CCSprite spriteWithFile:screenshotPath];

Note que después de salvar CCRenderTexture con saveBuffer como un PNG o archivo JPG, usted ya no tiene que tirar (scaleY =-1) el elfo cuando usted crea nuevo uno del archivo screenshot.

El screenshot al derecho muestra screenshot recientemente tomado dibujado sobre la escena actual, y despacio descoloración y alejar.

Sólo no espere crear un screenshot, o hasta sólo un con el tamaño de pantalla da la textura (sin salvar) sin un retraso de rendimiento sensible hasta en los últimos dispositivos. Esto no es definitivamente algo que usted querrá hacer mientras su juego comienza, pero es absolutamente fino para tomar un screenshot para un savegame o después de ganar el juego, por ejemplo.

El dibujo / Haciendo bosquejos con CCRenderTexture

Éste pica un rasguño y graba al agua fuerte un esbozo. En otras palabras: como usar CCRenderTexture para un dibujo o dibujar el programa. La diferencia principal que aquí es esto usted no quiere limpiar la textura dar cada vez usted comienza a dibujar a ella: 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:

//explícitamente no limpie el rendertexture
[los rtx comienzan];
color internacional = 0;;
  
para (UITouch* mencionan en contactos) touch in touches)
{
  Los CGPoint touchLocation = [tocan locationInView:director.openGLView];director.openGLView];
  touchLocation = [director convertToGL:touchLocation];touchLocation];

  //la posición debe ser convertida al espacio de nodo del elfo rtx
  touchLocation = [rtx.sprite convertToNodeSpace:touchLocation]; convertToNodeSpace:touchLocation];

  //porque el elfo es tirado a lo largo de su Eje Y,
  //la coordenada de Y también debe ser tirada:
  touchLocation.y = rtx.sprite.contentSize.height - touchLocation.y;.contentSize.height - touchLocation.y;

  //ponga el cepillo en aquella posición y délo
  brush.position = touchLocation;
  [mí setBrushColor:color ++];];
  [cepille la visita];
}
  
[final de rtx];

Importante para considerar es el hecho que las posiciones de toque deben ser convertidas al espacio de nodo del elfo de la textura dar. La tentativa de convertir la posición de toque al espacio de nodo de la textura dar no le dará los resultados correctos. Además, ya que la textura del elfo es al revés, la coordenada de touchLocation.y también debe ser invertida de modo que el origen (0, 0) la coordenada esté con eficacia en la esquina izquierda superior de la textura. 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.

Otra curiosidad a unos puede ser como soy capaz de iterar sobre los objetos de UITouch. Es la práctica común para "coleccionar" toques en una serie o simplemente reteniendo el NSSet. En este caso fui con una serie. Cada nuevo toque es añadido a la serie, y siempre que un toque se termine es quitado: 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 *) tocan withEvent: (UIEvent *) acontecimiento ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
  //añada nuevos toques a la serie ya que ellos entran
  [toques addObject:touch];;
  devuelva;
}

- (vacío) ccTouchEnded: (UITouch *) tocan withEvent: (UIEvent *) acontecimiento) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
  //debe quitar los toques que se han terminado o donde anulado
  [toques removeObject:touch];;
}

- (vacío) ccTouchCancelled: (UITouch *) tocan withEvent: (UIEvent *) acontecimiento) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event
{
  [mí ccTouchEnded:touch withEvent:event];event];
}

Mientras un dedo permanece en la pantalla que el objeto de UITouch* correspondiente permanece en la memoria y sólo actualiza sus propiedades. Iterando sobre los toques ponen en orden puedo dibujar nodos en la posición de cada dedo, aun cuando uno o varios dedos no se mueven. Esto permite el elfo que es dado con la opacidad muy baja para hacerse más opaco el más largo usted sigue tocando la misma posición, desde la interpretación del mismo elfo tiempos múltiples sin limpiar la textura dar se hacen una operación aditiva. 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.

Hacer bosquejos con una textura dar tiene un inconveniente significativo: usted no puede deshacer. Lo que es dibujado en la textura permanece para siempre. Usted no puede llevarse el más reciente, o cualquiera, dibujar órdenes. Usted sólo puede limpiar la textura entera y dejar al usuario comenzar. 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.

Sin embargo, usted puede conseguir algunos resultados chulos como visto en el screenshot.

Aspecto borroso del Movimiento de Fullscreen con CCRenderTexture

Una vez que yo era capaz de dar los contenido de la pantalla en una textura separada, yo tenía la idea de poner en práctica una utilización de efecto de aspecto borroso de movimiento CCRenderTexture. El principio es relativamente simple:

  • Cree múltiple dan texturas
  • Dé la pantalla corriente en "lo menos recientemente dibujado para” dar la textura
  • Dibuje todos dan texturas con la opacidad creciente, en el pedido de lo menos recientemente dibujado a hasta el que que fue actualizado sólo con los contenido de la pantalla

Esto crea un efecto de aspecto borroso no haciendo nada más que añadir imágenes de la oposición con la transparencia creciente. Usted puede ver el efecto final en el screenshot a la derecha.

La primera tarea es crear las texturas dar, en ausencia 4. Más y el precio de marco se cae demasiado lejos, cualquiera menos y el efecto simplemente tan pronunciado como me gustaría esto ser. Ya que quiero el efecto de aspecto borroso de dar normalmente con la transparencia, creo un CCSprite de cada uno dan la textura y sólo añaden los nuevos elfos a la lista de niños de la escena. Las texturas dar son retenidas en una serie en cambio. Para ser capaz de conseguir CCSprite correspondiente de cada uno dan la textura también adjudico el renderSprite a la propiedad userData de la textura dar: 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];
los renderTextures = [renderTextures retienen];;

para (intervalo i = 0; yo <kRenderTextureCount; yo ++) 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;;
    
  [mí addChild:renderSprite z:100 + yo];100 + i];
  rtx.userData = renderSprite;
  [renderTextures addObject:rtx];;
}

Ahora viene la parte inteligente. Ya que la escena sólo debería ser dibujada en una textura dar, y luego la escena debería dibujarse de los 4 dan elfos de textura, decidí superponer el método de visita y explícitamente no llamo la realización súper. Esto permite que yo consiga control lo que es dado donde. That allows me to gain control over what is rendered where.

Primero comienzo dibujando todos los nodos enturbiados por el movimiento (etiqueta == 10) en actualmente seleccionado dan la textura. Entonces pido de nuevo las texturas dar de lo menos recientemente dibujado a más recientemente dibujado con el aumento z pedido y aumento de la opacidad. Al mismo tiempo la llamada a selectNextRenderTexture también asegurará que la siguiente visita dibujará a lo menos recientemente dibujado dan la textura. At the same time the call to selectNextRenderTexture will also ensure that the next visit will draw to the least recently drawn render texture.

Finalmente, simplemente llamo la visita en cualquier nodo que no tenga la etiqueta 10 para darlos. Esto incluye los elfos de textura dar más cualquier otro nodo como etiquetas o el botón trasero.

- visita (vacía)) visit
{
 //fuerce el dibujo manual no llamando la visita súper...
 //[visita súper];

 //dé en siguiente rendertexture
 CCRenderTexture* rtx = [renderTextures objectAtIndex:renderTextures objectAtIndex:
   currentRenderTextureIndex];
 [rtx beginWithClear:0 g:0 b:0 a:0]; g:0 b:0 a:0];

 Nodo de CCNode*;
 CCARRAY_FOREACH ([mí niños], nodo), node)
 {
  si (node.tag == 10) == 10)
  {
   [visita de nodo];
  }
 }

 [final de rtx];
  
 //pida de nuevo las texturas dar de modo que el
 //la textura más recientemente dada es dibujada última
 [selectNextRenderTexture];
 índice internacional = currentRenderTextureIndex;
 para (intervalo i = 0; yo <kRenderTextureCount; yo ++) 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) * (yo + 1);255.0f / kRenderTextureCount) * (i + 1);
  [mí reorderChild:renderSprite z:100 + yo];100 + i];
  [selectNextRenderTexture];
    
  índice ++;
  si (índice> = kRenderTextureCount) { kRenderTextureCount) {
   índice = 0;
  }
 }
  
 //dibuje cualquier nodo restante
 CCARRAY_FOREACH ([mí niños], nodo), node)
 {
  si (¡node.tag! = 10) != 10)
  {
   [visita de nodo];
  }
 }
}

Quité la imagen de fondo para esta demostración de modo que el efecto de aspecto borroso de movimiento sea más evidente. Como sensible sin embargo es una gota en el rendimiento, por ejemplo en un iPod 4 a aproximadamente 40 fps. Esto es muy probable debido al hecho que hay 4 texturas fullscreen dadas. This is very likely because of the fact that there are 4 fullscreen textures being rendered.

El ejemplo de aspecto borroso de movimiento en el proyecto de demostración irá en bicicleta cada 20 segundos de limpiado o de no limpiado las texturas dar. En el caso último usted puede crear un efecto parecido a caleidoscope, como visto en el screenshot a la derecha.

Pixeles de juego con CCTexture2DMutable aka CCMutableTexture2D

Otra pregunta con frecuencia hecha: ¿Cómo poner/ponerse pixeles de una textura con Cocos2D?

Hay una clase CCTexture2DMutable comúnmente usada que flota alrededor de que fue al principio fijado aquí por Lam Hoang Pham. Hay una variedad de versiones que flotan alrededor pero la clase CCTexture2DMutable más moderna (por manucorporat) está aquí.

Con esto, usted puede crear un elfo que usa una textura mudable:

//inicialice una textura mudable con un bloque del juego de memoria al blanco
CGSize texSize = CGSizeMake (128, 128);, 128);
bytes internacionales = texSize.width * texSize.height * 4; * texSize.height * 4;
textureData = malloc (bytes);bytes);
memset (textureData, INT32_MAX, bytes);;

CCMutableTexture2D* tex = [[CCMutableTexture2D alloc] [CCMutableTexture2D alloc]
    initWithData:textureData
     pixelFormat:kCCTexture2DPixelFormat_RGBA8888
     pixelsWide:texSize.width
     pixelsHigh:texSize.height
     contentSize:texSize];
[autoliberación de tex];
    
//no incapacite la filtración de textura (ningún allanamiento, pixeles claros y crujientes)
[tex setAliasTexParameters];
    
elfo = [CCSprite spriteWithTexture:tex];tex];

Usted puede echar entonces la textura de aquel elfo a un CCMutableTexture2D y llamar su método setPixelAt de cambiar el color del pixel en la posición dada. Cuando usted es hecho actualizando la textura mudable, usted también tiene que llamar se aplican de modo que los cambios se hagan visibles:

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());
los ccColor4B colorean = 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];
[los tex se aplican];

La adquisición de un pixel es hecha de una moda similar con pixelAt:

los ccColor4B colorean = [tex pixelAt:randomPos];randomPos];

El proyecto de demostración dibuja un color que cambia a pixeles arbitrarios en la textura. La textura es aumentada y la filtración de textura es apagada de modo que los pixeles sean más fácilmente visibles.

¿CCRenderTexture mudable?

De la curiosidad hice una subclasificación de experimento CCRenderTexture y modificación del método init entonces esto usaría CCTexture2DMutable. Mientras esto trabajó perfectamente en el Simulador, esto se estrella en dispositivos iOS actuales. Entonces parece que usted no puede casarse con CCRenderTexture y CCTexture2DMutable. So it seems you can not marry CCRenderTexture and CCTexture2DMutable.

A fin de poner o cambiar los pixeles en CCRenderTexture usted puede usar órdenes de dibujo de OpenGL regulares, o hacer el uso de métodos de dibujo de conveniencia Cocos2D’s como ccDrawPoint.

El proyecto de demostración de CCRenderTexture


Agárrelo aquí. Este proyecto también está disponible en mi depósito github donde recibo todo el código fuente iDevBlogADay. where I host all of the iDevBlogADay source code.

El código es libre de usar y modificar lo que quiera. Todo mi código está según la Licencia de MIT, el CCTexture2DMutable no tiene ninguna licencia claramente identificable, pero fue dicho ser utilizable “tan libremente como usted desea”.

¡Como de costumbre, si usted tiene cualquier pregunta no dudan en preguntar! ¡Y si usted disfrutó de este correo no olvidan de piar, como o más - un esto, gracias!


¡Ayúdeme a ayudarle!

Paso mi tiempo entero subiendo con nuevas ideas que le ayudarán a hacerse un mejor revelador app. Muchísimo disfruto del proceso de aprendizaje, empujar de límites (mío y suyo y aquella de la tecnología), teniendo la libertad de perseguir independientemente de lo que está en mi mente o suya, a vigorosamente el programa lo que nadie ha programado antes, y escribir sobre que he aprendido. Ayúdeme a ayudarle hojeando los productos en Aprender la Tienda de Cocos2D. Help me help you by browsing the products in the Learn Cocos2D Store.


¡Cada venta permite que yo siga escribiendo mejor código, más seminarios y respuestas provechosas!
Etiquetado con:    

7 Respuestas a “Como usar CCRenderTexture para el Aspecto borroso de Movimiento, Screenshots y Drawing Sketches”

  1. Andrew dice:

    ¿Cómo puede esto ser usado?

    Tengo esta idea en mi cabeza, por favor corríjame donde estoy equivocado.

    Imagine un elfo complejo hecho de modelos que repiten colocado para hacerlo significativo, la base de aquel modelo es una imagen esto es repetido por todas partes de ello.

    ¿Podría yo salvar la memoria en la talla app por la inclusión sólo que pequeña imagen como una imagen de textura (digamos.png) y luego usar el código para distribuirlo alrededor en un avión virtual, luego dar esto a CCRenderTexture y luego usar aquel CCRenderTexture como un elfo?

    ¿O pienso en CCRenderTexture completamente incorrectamente?

    • Sí, usted puede reducir su talla app añadiendo sólo una pequeña imagen que es usada para dar un modelo. Sin embargo, usted no necesita una textura dar para dar el modelo. Si usted usa una hornada de elfo usted puede dar aquel modelo de varios elfos usando la misma imagen y será tan rápido. Usted también podría usar un tilemap para crear aquel modelo. Finalmente, hay parámetro de textura GL_REPEAT con el cual usted puede definir un área (rectángulo) sobre el cual una textura sola será repetida, supongo que será la opción más rápida. 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. Paul Gee dice:

    Hola Steffen,

    Gran artículo.

    ¿Es posible usar efectos como CCLens3D en un elfo en CCRenderTexture? ¿Si tan cómo?

    • No sé pero yo supondría que si la acción de lente corre en el elfo, simplemente llamando [la visita de elfo] para darlo también debiera dar el efecto de lente en su estado actual.

      • Paul Gee dice:

        No parece cuando usted trata sólo de dar CCRenderTexture independiente que usted quiere exportar como una foto.

        • Paul Gee dice:

          La cuestión era CCGrid3D es limitado con la utilización de la talla de ventana, tan cuando usted se presenta un CCLens3D a una textura dar de dicen 2048 1536 x que esto prendía. La subclasificación de CCGrid3D y añadiendo un initializer que construye una textura a la talla de la imagen, más la anulación de los 2dos & 3ros métodos de proyección de trabajar con la talla de imagen y no la talla de ventana trabajó … encantador

  3. [...] KKScreenshot de Screenshots, Aspecto borroso de Movimiento y Dibujando con correo de CCRenderTexture [...]

Deje una Respuesta