我有一个Metal纹理,我想通过使它成为一个float4数组从Swift访问它的数据(这样我就可以访问每个像素的4个颜色组件)。
我发现了[
"attribute": "image",
"format": "raw",
"value": function($model){
return ($model->image) ? Html::img("/path-to-img-location" . $model->image) : false;
}
]
的这种方法:
MTLTexture
我根本不知道如何使用UnsafeMutableRawPointer,它是如何工作的,以及如何将数据恢复到一个简单的Swift数组中。
我的第一次尝试是创建一个指针并分配足够的空间,但我甚至不知道这是不是我应该做的:
getBytes(UnsafeMutableRawPointer, bytesPerRow: Int, bytesPerImage: Int, from: MTLRegion, mipmapLevel: Int, slice: Int)
然后我根本不知道如何将这些数据恢复到标准的Swift数组......
谢谢。
答案 0 :(得分:11)
首先,我们假设你有一个UnsafeRawPointer
和一个长度:
let ptr: UnsafeRawPointer = ...
let length: Int = ...
现在您要将其转换为[float4]
。首先,您可以通过将UnsafeRawPointer
绑定到类型:
let float4Ptr = ptr.bindMemory(to: float4.self, capacity: length)
转换为类型指针
let float4Buffer = UnsafeBufferPointer(start: float4Ptr, count: length)
现在您可以将其转换为类型化缓冲区指针:
let output = Array(float4Buffer)
由于缓冲区是一个集合,你可以用它初始化一个数组:
UnsafeRawPointer
有关使用a = [{'1':'value1'},{'2':'value2'}]
b = [{'x':'value1'},{'y':'hello'},{'z':'value1'}]
的更多信息,请参阅SE-0138,SE-0107和UnsafeRawPointer Migration Guide。
答案 1 :(得分:3)
另一种选择是创建适当大小的数组 并将地址传递给函数的底层存储:
For Each cel
在结束内,For Each cel In Intersect(.Rows(irow), .Range(iCol))
是Private Sub cmdAdd_Click()
Dim irow As Long
Dim lastRow As Long
Dim iCol As String
Dim c As Range
Dim ws As Worksheet
Dim value As Long
Dim NewPart As Boolean
Dim ws_warehouse(7) As Worksheet '7 is total warehouse tab you have
Dim cel As Range
Set ws = Worksheets("Main")
Set ws_warehouse(1) = Worksheets("Elkhart East")
Set ws_warehouse(2) = Worksheets("Tennessee")
Set ws_warehouse(3) = Worksheets("Alabama")
Set ws_warehouse(4) = Worksheets("North Carolina")
Set ws_warehouse(5) = Worksheets("Pennsylvania")
Set ws_warehouse(6) = Worksheets("Texas")
Set ws_warehouse(7) = Worksheets("West Coast")
Set c = ws.Range("A7:A1048576").Find(What:=Me.PartTextBox.value, SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues, LookAt:=xlWhole)
If c Is Nothing Then
'find first empty row in database
lastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
irow = lastRow + 1
NewPart = True
Else
'find row where the part is
irow = ws.Cells.Find(What:=Me.PartTextBox.value, SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).Row
NewPart = False
End If
'check for a part number
If Trim(Me.PartTextBox.value) = "" Then
Me.PartTextBox.SetFocus
MsgBox "Please Enter A Part Number"
Exit Sub
End If
If Trim(Me.MonthComboBox.value) = "" Then
Me.MonthComboBox.SetFocus
MsgBox "Please Enter A Month"
Exit Sub
End If
If Trim(Me.AddTextbox.value) = "" Then
Me.AddTextbox.SetFocus
MsgBox "Please Enter A Value To Add Or Substract"
Exit Sub
End If
Select Case MonthComboBox.value
Case "Current Month"
iCol = "C:C,S:S"
Case "Current Month +1"
iCol = "N:R"
Case "Current Month +2"
iCol = "O:R"
Case "Current Month +3"
iCol = "P:R"
Case "Current Month +4"
iCol = "Q:R"
End Select
actWarehouse = Me.warehousecombobox.ListIndex + 1
With ws
.Cells(irow, "A").value = Me.PartTextBox.value
For Each cel In Intersect(.Rows(irow), .Range(iCol))
cel.value = cel.value + CLng(Me.AddTextbox.value)
cel.Interior.ColorIndex = 6
Next cel
End With
With ws_warehouse(actWarehouse)
'find part number
l_row = .Range("A" & .Rows.Count).End(xlUp).Row
NewPart = True
For r = 7 To l_row
If Trim(.Range("A" & r)) = "" Then Exit For
If LCase(.Range("A" & r)) = LCase(Me.PartTextBox.Text) Then
irow = r
Exit For
NewPart = False
End If
Next r
If NewPart Then irow = r
.Cells(irow, "A").value = Me.PartTextBox.value
For Each cel In Intersect(.Rows(irow), .Range(iCol))
cel.value = cel.value + CLng(Me.AddTextbox.value)
cel.Interior.ColorIndex = 6
Next cel
End With
'clear the data
Me.PartTextBox.value = ""
Me.MonthComboBox.value = ""
Me.AddTextbox.value = ""
Me.PartTextBox.SetFocus
Me.warehousecombobox.value = ""
End Sub
Private Sub cmdClose_Click()
Unload Me
End Sub
将数组存储表示为字节的集合,和
var pixelData = Array(repeating: float4(), count: myTextureSizeInFloat4)
pixelData.withUnsafeMutableBytes {
texture.getBytes($0.baseAddress!, ...)
}
是指向第一个字节的指针。
答案 2 :(得分:1)
补充@VasilyBodnarchuk的答案:
extension UnsafeMutableRawPointer {
func toArray<T>(to type: T.Type, capacity count: Int) -> [T] {
return Array(UnsafeBufferPointer(start: bindMemory(to: type, capacity: count), count: count))
}
}
答案 3 :(得分:0)
error: invalid operands of types ‘double(double) throw ()’ and ‘double’ to binary ‘operator+’
y = y0 + R;
~~~^~~
#include <iostream>
#include <cmath>
double y0, y, R;
int main() {
std::cin >> y0 >> R;
y = y0 + R;
}