【问题标题】:Particle system from texture doesn't load纹理中的粒子系统未加载
【发布时间】:2013-03-18 02:50:04
【问题描述】:

我正在尝试使用粒子系统为纹理加载粒子。由于这只是一个练习,我可以“手动”生成纹理。所以在这种情况下,我只是分配一个数据缓冲区并用红色(RGBA 32 位格式)填充它。

但问题是当程序开始运行时,我只看到黑屏,并没有我期望看到的内容(一些红色颗粒在移动)。

我解释了我在 cmets 中要做什么:

if( (self=[super init]))
{
    NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];

    uint32_t mask= 255+pow(255, 4); // This is a 32 bit red pixel
    NSUInteger size=256; // The texture is 256x256
    void* buffer= malloc(size*size*4); // Here I hold the data, it will be all red
    for(NSUInteger i=0; i<size; i++)
    {
        for(NSUInteger j=0; j<size; j++)
        {
            memcpy(buffer+j+i*32, &mask, 4);
        }
    }
    NSData* data=[[[NSData alloc]initWithBytesNoCopy: buffer length: size*size*4 freeWhenDone: YES]autorelease];  // I wrap it into NSData to automatically release it later. 
    CCTexture2D* texture=[[[CCTexture2D alloc]initWithData: data.bytes pixelFormat: kCCTexture2DPixelFormat_RGBA8888 pixelsWide: size pixelsHigh: size contentSize: CGSizeMake(size, size)]autorelease];
    CCParticleSystemQuad* system=[[[CCParticleSystemQuad alloc]initWithTotalParticles: 100]autorelease];
    system.texture= texture;  // I set the texture in a way that it should be load to draw particles
    system.position= ccp(200, 200);
    system.startSize= 10;
    system.endSize= 5;
    system.duration= kCCParticleDurationInfinity;
    system.life= 1;
    [self addChild: system]; 

    [pool drain];
}

使用图片

我尝试以使用 UIImage 而不是手动创建的纹理的方式修改代码:

if( (self=[super init]))
{
    // Even with glClearColor() it doesn't work
    //glClearColor(1, 0, 1, 1);
    NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init];

    NSBundle* bundle=[NSBundle mainBundle];
    NSString* path=[bundle pathForResource: @"fire" ofType: @"png"];
    UIImage* image=[UIImage imageWithContentsOfFile: path];
    CCTexture2D* texture=[[[CCTexture2D alloc]initWithImage: image]autorelease];
    CCParticleSystemQuad* system=[[[CCParticleSystemQuad alloc]initWithTotalParticles: 100]autorelease];
    system.texture= texture;
    system.startSize= 10;
    system.endSize= 10;
    system.life= 1;
    system.duration= kCCParticleDurationInfinity;
    system.position= ccp(200, 200);
    // Even changing the start/end color it doesn't work
    //system.startColor= (ccColor4F){1.0,0.0,0.0,1.0};
    //system.endColor= (ccColor4F){1.0,0.0,0.0,1.0};
    system.emitterMode= kCCParticleModeGravity;
    system.gravity= ccp(200, 200);
    system.speed=1;
    [self addChild: system];

    [pool drain];
}

app bundle 中的图片“fire.png”是:

我还设置了一些其他属性,但还是不行:黑屏。

【问题讨论】:

  • 使用 memset(buffer, &mask, size*size*4) 一次只用一种颜色填充缓冲区,for循环和每次迭代复制4个字节非常无效
  • NSData 是不必要的,直接将缓冲区传递给 CCTexture2D 并在之后的行中释放(缓冲区)。这没关系,因为 CCTexture2D 将数据从缓冲区复制到实际纹理中,并且不再需要缓冲区。这里的 NSAutoreleasePool 也是完全没有必要的(并且池正在泄漏,因为您不释放它..考虑使用 ARC)。
  • 关于memset:它只占用第一个字节,但我有一个4字节整数,这就是我使用循环的原因。关于池:我应该使用释放而不是自动释放并删除自动释放池吗?顺便说一句 [pool drain] 释放池。
  • memset 设置 n 个整数值,它会填满整个缓冲区就好了。这里的自动释放池根本没有什么可做的,或者只有非常非常少的事情要做。这不像您在池的 init 和 drain 之间创建数百个自动释放对象(不知道这是 release 的别名)。
  • 这里需要设置的位掩码是 255+255^4 。 memset() 将此数字转换为无符号字符,并将每个字节设置为 255(转换后的数字)。

标签: iphone ios objective-c cocos2d-iphone particle-system


【解决方案1】:

我想到了一些事情(除了代码改进,请参阅我的 cmets):

更改清除颜色,只是为了查看粒子系统是否可能正在运行但只产生黑色粒子:

glClearColor(1, 0, 1, 1);

粒子系统本身可能没有正确配置(数据不完整,属性使用默认值,通常只有 0)。您未修改的属性可能会导致粒子系统渲染不正确。例如,粒子系统具有 startColor 和 endColor 属性。如果它们都被初始化为黑色或透明颜色,因为您没有将它们设置为更亮的(白色)颜色,那么无论您的纹理具有什么颜色,粒子都是黑色的。我相信这很可能是这里发生的事情。

首先尝试使用图像文件中的常规纹理设置粒子系统。如果您已确认粒子系统创建了可见的非黑色粒子,则可以切换到使用您的自定义纹理。

【讨论】:

  • 我尝试使用从图像创建的纹理,但它不起作用,我编辑了问题。
【解决方案2】:

我最终使用粒子薄荷创建粒子系统,然后使用工厂方法:

CCParticleSystemQuad* system=[[[CCParticleSystemQuad alloc]initWithDictionary: [ParticleFactory makeEffect]]autorelease];

【讨论】:

    猜你喜欢
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多