小编J.D*_*Doe的帖子

如何在OpenGL es 2.0中模拟累积缓冲区(尾随粒子效应)

所以我一直试图用OpenGL ES 2.0 创建一个尾随粒子效果(见到这里).不幸的是,似乎OpenGL命令(累积缓冲区)无法在OpenGL中使用.这意味着有必要走长路.

主题描述了执行此类操作的可能方法.但是我对如何在缓冲区中存储内容并组合缓冲区感到很困惑.所以我的想法是做以下事情.

  1. 使用写入纹理的缓冲区将当前帧绘制到纹理中
  2. 将之前的帧(但已淡入)绘制到另一个缓冲区中.
  3. 将步骤1置于步骤2的顶部.然后显示.
  4. 保存显示的任何内容以供下一帧使用.

到目前为止,我的理解是缓冲区以与纹理相同的方式存储像素数据,只需使用着色器可以更容易地绘制缓冲区.

因此,想法可能是渲染到缓冲区,然后将其移动到纹理中.

我发现这样做的一个理论就是这个

回想起来,你应该创建两个FBO(每个都有自己的纹理); 使用默认的帧缓冲区是不可靠的(不保证在帧之间保留内容).

绑定第一个FBO后,清除它然后正常渲染场景.渲染场景后,使用纹理作为源并使用混合将其渲染到第二个FBO(第二个FBO永远不会被清除).这将导致第二个FBO包含新场景和之前的场景的混合.最后,第二个FBO应直接渲染到窗口(这可以通过渲染纹理四边形来完成,类似于前一个操作,或者使用glBlitFramebuffer).

实质上,第一个FBO取代了默认的帧缓冲区,而第二个FBO取代了累积缓冲区.

综上所述:

初始化:

对于每个FBO: - glGenTextures - glBindTexture - glTexImage2D - glBindFrameBuffer - glFramebufferTexture2D

每一帧:

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo1)glClear glDraw*//场景

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,fbo2)glBindTexture(tex1)glEnable(GL_BLEND)glBlendFunc glDraw*//全屏四边形

glBindFrameBuffer(GL_DRAW_FRAMEBUFFER,0)glBindFrameBuffer(GL_READ_FRAMEBUFFER,fbo2)glBlitFramebuffer

不幸的是它没有足够的代码(尤其是初始化让我开始).

但我已经尝试过,到目前为止我所得到的只是一个令人失望的空白屏幕.我真的不知道我在做什么,所以可能这段代码是错误的.

var fbo1:GLuint = 0
var fbo2:GLuint = 0
var tex1:GLuint = 0

Init()
{
    //...Loading shaders  OpenGL etc.   
    //FBO 1
        glGenFramebuffers(1, &fbo1)
        glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo1)

        //Create texture for shader output
        glGenTextures(1, &tex1)
        glBindTexture(GLenum(GL_TEXTURE_2D), tex1)
        glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGB, width, height, 0, GLenum(GL_RGB), …
Run Code Online (Sandbox Code Playgroud)

opengl-es ios opengl-es-2.0 swift

10
推荐指数
1
解决办法
733
查看次数

在不删除线程锁的情况下优化代码

我试图在一个已经很疯狂的应用程序上放置一个波纹模拟.现在cpu在最低处理器上运行大约11ms.到目前为止,它中的所有代码都在主线程上运行.

我希望可以将纹波模拟完全放在另一个线程上.

该模拟基于Apple GLCameraRipple项目.基本上它会创建一个镶嵌的矩形,并计算纹理坐标.因此,在理想的世界中,纹理坐标和纹波模拟数组都将位于不同的线程上.

我正在使用的更新功能现在看起来像这样.它确实可以利用GCD,但由于同步,它不会因此而获得速度.没有同步但是应用程序会崩溃,因为swift数组不是线程安全的.

var rippleTexCoords:[GLfloat] = []
var rippleSource:[GLfloat] = []
var rippleDest:[GLfloat] = []
func runSimulation()
{
    if (firstUpdate)
    {firstUpdate = false; Whirl.crashLog("First update")}

    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)     
    let block1: (y: size_t) -> Void = {
    (y: size_t) -> Void in

    objc_sync_enter(self)
    defer { objc_sync_exit(self) } // */ This will actually run at the end

    let pw = self.poolWidthi
    for x in 1..<(pw - 1)
    {
        let ai:Int = (y    ) * (pw + 2) …
Run Code Online (Sandbox Code Playgroud)

multithreading grand-central-dispatch ios swift

10
推荐指数
1
解决办法
421
查看次数

这段代码如何在swift中找到Struct的内存对齐大小?为什么需要二进制操作?

我正在通过Metal iOS Swift示例尝试了解他们建议的三重缓冲实践.这是在演示内部显示的统一动画.

据我所知,对齐内存只是以一个特定的增量开始,这是设备真正喜欢的某个字节数的倍数.我的困惑是这行代码

// The 256 byte aligned size of our uniform structure
let alignedUniformsSize = (MemoryLayout<Uniforms>.size & ~0xFF) + 0x100
Run Code Online (Sandbox Code Playgroud)

他们用它来查找Uniforms结构的大小和字节.我很困惑为什么在这里有二进制操作我真的不确定他们做了什么.

如果它有助于这个对齐的大小用于创建这样的缓冲区.我很确定缓冲区会自动分配字节对齐的内存,因此可以用作制服的内存存储位置.

let buffer = self.device.makeBuffer(length:alignedUniformsSize * 3, options:[MTLResourceOptions.storageModeShared])
Run Code Online (Sandbox Code Playgroud)

所以基本上不是经历自己分配字节对齐内存的麻烦,而是让金属为它们做.

在那个时候,他们的策略时,他们没有使用任何理由let allignedUniformsSize =不会为其他类型,比如上班IntFloat等?

xcode ios swift metal

10
推荐指数
1
解决办法
512
查看次数

警报"登录iTunes Store"和"电池电量不足"会暂停我的应用程序卡纸.我怎样才能取消它们?

我的应用程序中有一些音乐可以播放AVAudioSessionCategoryAmbient.现在我的问题是,当Apple弹出一个像"登录iTunes Store"的弹出窗口时,它会暂停我的音乐,但不会恢复它.值得庆幸的是,它照顾了我SKScene......但不是音乐.是否有某种方法可以在警报解除时进行回调?

奇怪的是,UIAlertView我制作的其他内容不会对应用程序执行此操作,所以我真的不知道是什么.

暂停场景和音乐的警报列表:

  • 登录itunes
  • 电量不足
  • 确认购买

iphone avaudioplayer ios swift

6
推荐指数
1
解决办法
214
查看次数

MacOS 在后台不响应 MPRemoteCommandCenter 命令

我正在为我自己的目的编写一个应用程序,旨在无论系统中发生什么都可以获得播放暂停事件。我已经做了这么多工作

let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("Play Pause Command")
    return .success
}

commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("NextTrackCommand")
    return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("previousTrackCommand")
    return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
    print("playCommand")
    return .success
}

MPNowPlayingInfoCenter.default().playbackState = .playing
Run Code Online (Sandbox Code Playgroud)

大多数方法都在那里,因为很明显,如果没有实现 nextTrackCommand 或 previousTrackCommand 或 playCommand ,您将不会收到任何通知。

无论如何,我的一个问题是,一旦您打开另一个使用音频的应用程序,这些事件处理程序就会停止调用,我无法找到检测和解决此问题的方法。

我通常会尝试做 AVAudioSession 事情来将其声明为后台应用程序,但这似乎不起作用。无论系统处于何种状态,关于如何获得游戏暂停事件的任何想法?

我希望能够始终收听这些事件或获得其他人何时控制音频的指示?也许甚至可以重新订阅这些播放暂停事件。

macos xcode cocoa mpremotecommandcenter

6
推荐指数
1
解决办法
244
查看次数

如何在我的应用程序上创建另一个屏幕

所以我想知道,默认的"游戏"Xcode配置.你会如何制作另一款SKScene?比如说我想要一个菜单​​或什么?

基本上我将如何创建另一个标题为"title.swift"的文档,然后以编程方式来回切换它们?这样我可以从菜单到游戏场景而不会弄乱我的代码?

我无法在重新编码的代码中找到它实际上告诉swift显示用"游戏"配置预制的游戏场景.

我想我创建了一个新类并继承了SKScene.

xcode sprite-kit swift

5
推荐指数
1
解决办法
204
查看次数

请帮我正确应用设备旋转数据

所以我有一个我想做的项目.我试图让设备相对于重力旋转,并从它开始的位置进行平移.所以基本上为设备获取"跟踪"数据.我打算基本上通过制作一个3d pt来模拟我稍后从设备上记录的数据.

无论如何要尝试实现这一点,我认为最好使用场景工具包,这样我就可以看到三维中的东西,就像我想要记录的数据一样.现在我一直试图让船旋转,使它总是看起来像它的跟随重力(就像它在地面上或其他东西)无论设备旋转是什么.我想,一旦我把它弄下来,将这一点应用于某一点将是一个难题.所以我做了以下代码:

if let attitude = motionManager.deviceMotion?.attitude {
        print(attitude)


        ship.eulerAngles.y = -Float(attitude.roll)
        ship.eulerAngles.z = -Float(attitude.yaw)
        ship.eulerAngles.x = -Float(attitude.pitch)

    }
Run Code Online (Sandbox Code Playgroud)

当你只运行其中一条旋转线时,一切都很完美.它确实在该轴上表现良好.然而,当我同时完成所有三个轴时,它变得混乱并且与抖动和所有事情的预期相差很远.

我想我的问题是:有没有人知道如何修复上面的代码,以便无论方向如何,船都能正常保持"直立"状态.

ios gyroscope cmmotionmanager scenekit swift

5
推荐指数
1
解决办法
1523
查看次数

“MTLBuffer”类型的值没有成员“didModifyRange”

我很困惑,因为我在 Swift 4 中创建了一个 MTLBuffer,但无法使用 didModifyRange 方法。

有趣的是,我仍然可以在 Apple 文档中找到这一点,并且没有听说过这一点被改变了。

为什么会Value of type 'MTLBuffer' has no member 'didModifyRange'发生错误?

以下代码将在最新版本的 XCode 中生成此错误

let device = MTLCreateSystemDefaultDevice()
var buffer = device?.makeBuffer(length: 3, options: [])
let range = Range<Int>(NSRange())
buffer.didModifyRange(range)
Run Code Online (Sandbox Code Playgroud)

xcode ios swift metal

5
推荐指数
0
解决办法
447
查看次数

MTKTextureLoader使图像饱和

我正在尝试使用MTKTextureLoader加载CGImage作为纹理。这是原始图片

漂亮的形象

但是,当我将该CGImage转换为MTLTexture并将该纹理转换回CGImage时,它看起来很可怕,如下所示:

在此处输入图片说明

这是代码中正在发生的事情。

图像作为CGImage加载(我已经检查过了,该图像确实具有完整的视觉质量)

我有一个功能view(),可以通过在CALayer中使用它来查看NSImage,如下所示:

 func view() {
    .....
    imageView!.layer = CALayer()
    imageView!.layer!.contentsGravity = kCAGravityResizeAspectFill
    imageView!.layer!.contents = img
    imageView!.wantsLayer = true
Run Code Online (Sandbox Code Playgroud)

所以我做了以下

let cg = CoolImage()
let ns = NSImage(cgImage: cg, size: Size(width: cg.width, height: cg.height))
view(image: ns)
Run Code Online (Sandbox Code Playgroud)

并检查是否足够具有完整的视觉保真度。

因此,我将cg图像加载到MTLTexture中,如下所示

    let textureLoader = MTKTextureLoader(device: metalState.sharedDevice!)

    let options = [
        MTKTextureLoader.Option.textureUsage: NSNumber(value: MTLTextureUsage.shaderRead.rawValue | MTLTextureUsage.shaderWrite.rawValue | MTLTextureUsage.renderTarget.rawValue),
        MTKTextureLoader.Option.SRGB: false
    ]

    return ensure(try textureLoader.newTexture(cgImage: cg, options: options))
Run Code Online (Sandbox Code Playgroud)

然后,我将MTLTexture转换回UIImage,如下所示:

    let texture = self
    let width = texture.width
    let height = texture.height
    let bytesPerRow …
Run Code Online (Sandbox Code Playgroud)

nsview ios swift metal

5
推荐指数
1
解决办法
641
查看次数

金属 alpha 混合不起作用

无论出于何种原因,我都遇到了金属中 alpha 混合的问题。我正在绘制 MTKView,对于我创建的每个管道,我执行以下操作:

descriptor.colorAttachments[0].blendingEnabled = YES;
descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorSourceAlpha;
descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
Run Code Online (Sandbox Code Playgroud)

但是,无论出于何种原因,这都不会导致 alpha 测试发生。您甚至可以检查帧调试器,您将看到 alpha 为 0 的顶点被绘制为黑色而不是透明。

我的一个想法是,某些几何体最终位于完全相同的 z 平面上,因此如果 alpha 混合在同一 z 平面上不起作用,则可能会导致问题。但我不认为那是一回事。

为什么 alpha 混合不起作用?

我希望像透明玻璃一样混合。这样想。

在此处输入图片说明

graphics objective-c ios metal

4
推荐指数
1
解决办法
1630
查看次数