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

金属 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
查看次数

金属:我需要多个RenderPipelines才能具有多个着色器吗?

我对金属非常陌生,因此在从丑陋的OpenGL状态机调用过渡到现代图形框架时,请多多包涵。我真的想确保我了解所有事情如何一起工作。

我已经阅读了大多数Apple文档,但是在描述各个组件的功能方面它们比它们如何组合起来做得更好。

我试图从本质上理解我是否应该有多个renderPipelines和renderEncoders在我的情况下。

要在更高层次上描述我的管道,是这样的:

  1. 从渲染到的屏幕外纹理中检索前一帧的内容,并在其上绘制一些新内容。
  2. 切换到屏幕上的渲染。从第1步将纹理绘制到屏幕上。
  3. 做一些后期处理(以本机分辨率)。
  4. 在四边形上绘制UI。(essentailly重复2)

因此,从本质上讲,将存在以下顶点/片段着色器对

  • 绘制实体(步骤1)
  • 在指定区域上绘制四边形(步骤2和4)
  • 后处理着色器1(步骤3)使用的输入与D不同,并且不能在同一着色器中完成
  • 后期处理着色器2(第3步)使用的输入与C不同,并且无法在同一着色器中完成

将有以下纹理组

  • 每个UI元素的纹理
  • 步骤1中完成的屏幕外绘图的纹理
  • 取决于金属性能,后期处理中可能会使用更多的屏幕外纹理

最终我的困惑是:

  • Q1。渲染管线仅采用一个顶点和一个片段函数,所以这意味着即使我的绘制过程只有3个唯一的步骤,我也需要4个渲染管线吗?
  • Q2。我应该如何在一个编码器中使用多个管道?每个成功的调用都不会.setRenderPipelineState覆盖前一个吗?
  • Q3。您是建议.setFragmentTexture在创建编码器后立即保留所有呼叫,还是只需要在需要时立即设置这些呼叫。
  • Q4。即使在管道状态之间切换时,保持depthState不变也有效吗?如何确保第1步中的实体具有深度渲染,但要确保帧之间的深度信息丢失,因此实体都位于先前内容的顶部?
  • Q5。在具有两个后处理步骤的渲染步骤3中,我该怎么办?那些必须是单独的管道吗?
  • Q6。知道步骤2和步骤4在输入不同的情况下基本上是相同的,我如何才能有效地构建管道?

我想如果有人带我逐步了解我需要什么以及为什么需要它,它将对我有帮助。理解某些psuedocode级别的renderCommandEncoder命令可能看起来是很有用的。

graphics ios swift metal

3
推荐指数
1
解决办法
980
查看次数

是否有充分的理由阻止队列中的堆栈中的.peek()?

我在CS(Java)入门课程中,老师不允许我们在Queue或Stack上使用.peek().

显然,在堆栈上这是一个相当容易的解决方法,因为我们可能拥有任意数量的临时内注.可以简单地将值弹出到变量上并将其重新打开.这可能是它在幕后实施的方式.

在队列中,这会使事情变得复杂一些,但仍然可以完成.但是我不确定java如何实现queue.peek所以我不能在这里找到替换.

最终我很想知道.为什么不鼓励窥视堆栈和队列是一种好习惯?

java

2
推荐指数
1
解决办法
73
查看次数

将C ++代码桥接到我的快速代码中。XCode中哪些基于c语言的文件扩展名是什么?

作为Swift编码器,我对事物c方面的明显碎片感到困惑。不知何故,有Objective-C,Objective-C ++,c和c ++,它们都具有.h,.hpp,.m,.cpp等文件扩展名,但是我找不到关于哪个扩展名指向哪种文件类型的详尽文档。 XCode(尽管我相当确定c ++应该是.hpp和.cpp)。

这种混乱使我陷入困境,在尝试向快速代码公开C ++类时,我对自己的工作一无所知。让我解释一下我的策略。

我有一个由我修改过的XCode自动生成的桥接文件

桥接头

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#include <stdio.h>
#include <stdlib.h>

int* main1() {
    int *num;

    num = (int *)malloc(1000 * sizeof(int));
    for (int i = 0; i < 10; i++) {
        num[i] = i;
    }
    num[10] = 10;
    free(num);
    return num;
}
Run Code Online (Sandbox Code Playgroud)

如果我解释正确,那么XCode会将其视为Objective-C代码的头文件。确实,此功能可以迅速发挥作用并按预期工作。

然后,我创建了另一个文件,因为如果我尝试在该文件中导入我的c ++代码,它将尝试像objective-c一样编译它,但效果不佳。我相信该文件将是此标头的实现,并且我被告知这将是导入我的c ++代码的安全地方。

还有 Bridging-Header.m

#ifndef Bridging_Header_h
#define Bridging_Header_h
#import "Bridging-Header.h"
#import "rectangle.hpp"

int …
Run Code Online (Sandbox Code Playgroud)

c++ xcode objective-c ios swift

2
推荐指数
1
解决办法
1164
查看次数

如何在c ++代码中存储id <MTLBuffer>?

我正在编写一个跨平台引擎来进行渲染.我正在尝试创建一个跨平台结构,它基本上管理一种绘制的几何体.

目标是有一个c ++类,它为分配给缓冲区的内存块保存一个void*,然后将该指针传递给MTLBuffer或Vulcan Buffer以用于渲染.因此,这个类的一个领域需要是一个缓冲区,但在跨平台意义上.

对于我的绘图的一部分,代码应该是这样的

func draw() {
   CrossPlatformBuffers* buffs = // preset list
   for (buffer in buffs {
      PlatformSpecificEngine.drawWith((PlatformSpecificBuffer)buffs->buffer)
   }
}
Run Code Online (Sandbox Code Playgroud)

所以基本上我需要能够将我的MTLBuffer存储为c ++类中的void*.这让我感到困惑,因为我不确定c ++如何使用objective-c ARC或者id应该是什么意思.

如果我只是将id转换为void*并将其传递到c ++类中,然后将其称为delete,我会遇到任何问题吗?

c++ objective-c metal

2
推荐指数
1
解决办法
278
查看次数

glBufferData设置为null以便不断更改vbo

我有一个巨大的vbo,整个事情每一帧都在改变.

我听说过快速更改缓冲区数据的不同方法,但其中只有一个对我的程序来说是一个好主意.但是,我不理解它,无法找到任何代码示例.

我听说有人声称你应该用"null"作为数据调用glBufferData,然后用每帧填充真实数据.这是什么目的?这在代码中是什么样的?

opengl opengl-es

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

“ShaderTypes.h”中演示的金属着色器类型顶点和缓冲区最佳实践

这是完整的 shadertypes.h 文件。我将把它分解成我无法理解的部分。

#ifndef ShaderTypes_h
#define ShaderTypes_h

//Part 1 Compiler flags
#ifdef __METAL_VERSION__
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NSInteger metal::int32_t
#else
#import <Foundation/Foundation.h>
#endif

#include <simd/simd.h>

//Part 2 buffer index
typedef NS_ENUM(NSInteger, BufferIndex)
{
    BufferIndexMeshPositions = 0,
    BufferIndexMeshGenerics  = 1,
    BufferIndexUniforms      = 2
};

//Part 3 vertex attribute and position
typedef NS_ENUM(NSInteger, VertexAttribute)
{
    VertexAttributePosition  = 0,
    VertexAttributeTexcoord  = 1,
};

//Part 4 texture index color
typedef NS_ENUM(NSInteger, TextureIndex)
{
    TextureIndexColor    = …
Run Code Online (Sandbox Code Playgroud)

xcode objective-c ios swift metal

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

OpenGL ES透明度不起作用,而是只是与背景混合

所以我在手机上设置了一个简单的模拟.目标是在屏幕上显示带有各种透明度的红色,白色和蓝色圆圈.我有大部分工作,除了一件事,而透明度的工作,唯一的混合发生在黑色背景.结果,中心的圆圈显示为深红色,而不是在其下方显示白色圆圈.我究竟做错了什么?

注意我正在使用正交2d投影矩阵.所有对象z位置都相同,并以特定顺序呈现.

UH OH

以下是我如何设置透明度的方法:

glEnable(GLenum(GL_DEPTH_TEST))
glEnable(GLenum(GL_POINT_SIZE));
glEnable(GLenum(GL_BLEND))
glBlendFunc(GLenum(GL_SRC_ALPHA), GLenum(GL_ONE_MINUS_SRC_ALPHA))
glEnable(GLenum(GL_POINT_SMOOTH))
//Note some of these things aren't compatible with OpenGL-es but they can hurt right?
Run Code Online (Sandbox Code Playgroud)

这是片段着色器:

precision mediump float;
varying vec4 outColor;
varying vec3 center;
varying float o_width;
varying float o_height;
varying float o_pointSize;
void main()
{
    vec4 fc = gl_FragCoord;
    vec3 fp = vec3(fc);


    vec2 circCoord = 2.0 * gl_PointCoord - 1.0;


    if (dot(circCoord, circCoord) > 1.0) {
        discard;
    }

    gl_FragColor = outColor;//colorOut;
}
Run Code Online (Sandbox Code Playgroud)

以下是我将每个圆圈传递给着色器的方法:

func drawParticle(part: Particle,color_loc: GLint, size_loc: GLint) …
Run Code Online (Sandbox Code Playgroud)

opengl-es opengl-es-2.0 glkit swift

0
推荐指数
1
解决办法
347
查看次数

检测 MTLTexture 是否为空白

我试图通过计算每个像素的所有 RGB 和 A 分量的总和来确定 MTLTexture(bgra8Unorm 格式)是否为空白。

此函数旨在通过在将纹理复制到指针后在内存中添加相邻的浮点数来实现此目的。但是我已经确定,无论给定的 MTLTexture,这个函数最终都会返回 false。

这个功能有什么问题?

func anythingHere(_ texture: MTLTexture) -> Bool {
        let width = texture.width
        let height = texture.height
        let bytesPerRow = width * 4

        let data = UnsafeMutableRawPointer.allocate(bytes: bytesPerRow * height, alignedTo: 4)
        defer {
            data.deallocate(bytes: bytesPerRow * height, alignedTo: 4)
        }

        let region = MTLRegionMake2D(0, 0, width, height)
        texture.getBytes(data, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0)
        var bind = data.assumingMemoryBound(to: UInt8.self)

        var sum:UInt8 = 0;
        for i in 0..<width*height {
            sum += …
Run Code Online (Sandbox Code Playgroud)

ios swift metal

0
推荐指数
1
解决办法
807
查看次数

MTLDevice 类需要 id&lt;&gt;

我对 Objective-c 很陌生,所以请耐心等待,我仍在尝试理解可以在目标 c 中放置属性和类变量的众多位置。

我是一名经验丰富的 Metal 开发人员,但我几乎没有用 Objective-c 做过任何事情。

我正在尝试创建一个 MetalCore 类,该类将保存 MTLDevice、MTLCommandQueue 并促进应用程序核心管道等的创建。

因此,我定义了以下内容

@property (readonly, nonatomic, assign) MTLDevice* devicePtr;
Run Code Online (Sandbox Code Playgroud)

然而,在我的课堂上,Unknown type name MTLDevice; did you mean...即使我得到了错误#import <Metal/Metal.h>,这里发生了什么?

我查看了堆栈溢出并找到了人们定义这样的函数的示例

- (<MTLDevice> *)device;
Run Code Online (Sandbox Code Playgroud)

或者

- (instancetype)initWithDevice:(id<MTLDevice>) device;
Run Code Online (Sandbox Code Playgroud)

整个 id 和 <> 是怎么回事?在什么情况下可以省略 id 部分?

我觉得特别奇怪的是,虽然大多数 Metal 类型似乎都需要 id,但有些类似的MTLRenderPipelineDescriptor不需要它,实际上只在该Type*模式下工作。这是为什么,我如何从文档中确定需要什么?

objective-c ios metal

0
推荐指数
1
解决办法
743
查看次数

c ++结构名称中的指针

我遇到了一些c ++链表实现的代码.

struct node
{
    int info;
    struct node *next;
}*start;
Run Code Online (Sandbox Code Playgroud)

这意味着什么*start而不仅仅是start??

以后像这样使用会发生什么?什么s意思是它没有被函数中的任何其他地方引用?

struct node *temp, *s;
temp = new(struct node); 
Run Code Online (Sandbox Code Playgroud)

c++

-3
推荐指数
1
解决办法
382
查看次数

复制构造函数未在c ++类上删除

我试图创建一个永远不会重复的类,因为它的字段中有很多数据.为此,我定义了这样的类:

class Foo {
public:
   Foo(int i);
   Foo();
   Foo(const Foo&) = delete;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试执行以下操作,这会导致编译器错误:

Foo a(2);
Foo b = a;
Run Code Online (Sandbox Code Playgroud)

但无论出于何种原因,这都不包括复制数据的情况.

Foo* array;
array = new Foo[10000];
Foo a(2);
array[1] = a;
Run Code Online (Sandbox Code Playgroud)

为什么是这样?

c++

-3
推荐指数
1
解决办法
61
查看次数

标签 统计

ios ×6

metal ×6

objective-c ×5

swift ×5

c++ ×4

graphics ×2

opengl-es ×2

xcode ×2

glkit ×1

java ×1

opengl ×1

opengl-es-2.0 ×1