Skip to content

Commit 43cf146

Browse files
committed
Continue expanding functionality
1 parent 57016c8 commit 43cf146

File tree

2 files changed

+137
-16
lines changed

2 files changed

+137
-16
lines changed

Sources/GateEngine/Resources/Texture/Raw/RawTexture.swift

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,25 @@ public struct RawTexture: Sendable {
1313
self.imageSize = imageSize
1414
self.imageData = imageData
1515
}
16+
17+
public init(imageSize: Size2i) {
18+
self.imageSize = imageSize
19+
self.imageData = Data(repeating: 0, count: imageSize.width * imageSize.height * 4)
20+
for alphaIndex in stride(from: 3, to: self.imageData.count, by: 4) {
21+
self.imageData[alphaIndex] = .max
22+
}
23+
}
1624
}
1725

1826
public extension RawTexture {
1927
@inlinable
2028
nonmutating func color(at pixelCoordinate: Position2i) -> Color {
21-
return self[index(at: pixelCoordinate)]
29+
return self[index(for: pixelCoordinate)]
2230
}
2331

2432
@inlinable
2533
mutating func setColor(_ color: Color, at pixelCoordinate: Position2i) {
26-
self[index(at: pixelCoordinate)] = color
34+
self[index(for: pixelCoordinate)] = color
2735
}
2836

2937
@inlinable
@@ -38,38 +46,74 @@ public extension RawTexture {
3846
}
3947

4048
public extension RawTexture {
49+
@inlinable
50+
nonmutating func color(at textureCoordinate: Position2f) -> Color {
51+
let pixelCoord = self.pixelCoordinate(for: textureCoordinate)
52+
return self.color(at: pixelCoord)
53+
}
54+
55+
@inlinable
56+
mutating func setColor(_ color: Color, at textureCoordinate: Position2f) {
57+
let pixelCoord = self.pixelCoordinate(for: textureCoordinate)
58+
self.setColor(color, at: pixelCoord)
59+
}
60+
61+
@inlinable
62+
subscript(textureCoordinate: Position2f) -> Color {
63+
nonmutating get {
64+
return self.color(at: textureCoordinate)
65+
}
66+
mutating set {
67+
self.setColor(newValue, at: textureCoordinate)
68+
}
69+
}
70+
}
71+
72+
public extension RawTexture {
73+
func isAlphaChannelSubMax(at index: Int) -> Bool {
74+
return imageData[(index * 4) + 3] < .max
75+
}
76+
}
77+
78+
public extension RawTexture {
79+
/// The UV space size of a single pixel
80+
@inlinable
81+
var pixelSize: Size2f {
82+
return Size2f.one / Size2f(self.imageSize)
83+
}
4184
/// The UV position for the pixel
4285
@inlinable
43-
func textureCoordinate(at pixelCoordinate: Position2i) -> Position2f {
44-
return Position2f(
45-
x: Float(pixelCoordinate.x) / Float(imageSize.width),
46-
y: Float(pixelCoordinate.y) / Float(imageSize.height)
47-
)
86+
func textureCoordinate(for pixelCoordinate: Position2i) -> Position2f {
87+
let pixelSize = self.pixelSize
88+
return (Position2f(pixelCoordinate) * pixelSize) + (pixelSize / 2)
4889
}
4990

5091
@inlinable
51-
func textureCoordinate(at index: Index) -> Position2f {
52-
return self.textureCoordinate(at: self.pixelCoordinate(at: index))
92+
func textureCoordinate(for index: Index) -> Position2f {
93+
return self.textureCoordinate(for: self.pixelCoordinate(for: index))
5394
}
5495

5596
@inlinable
56-
func pixelCoordinate(at textureCoordinate: Position2f) -> Position2i {
57-
return Position2i(
58-
x: Int(Float(imageSize.width) * textureCoordinate.x),
59-
y: Int(Float(imageSize.height) * textureCoordinate.y)
60-
)
97+
func index(for textureCoordinate: Position2f) -> Index {
98+
return self.index(for: self.pixelCoordinate(for: textureCoordinate))
99+
}
100+
101+
@inlinable
102+
func pixelCoordinate(for textureCoordinate: Position2f) -> Position2i {
103+
let pixelSize = self.pixelSize
104+
return Position2i(textureCoordinate / pixelSize)
61105
}
62106

63107
@inlinable
64-
func pixelCoordinate(at index: Index) -> Position2i {
108+
func pixelCoordinate(for index: Index) -> Position2i {
65109
return Position2i(
66110
x: index % self.imageSize.width,
67111
y: index / self.imageSize.width
68112
)
69113
}
70114

71115
@inlinable
72-
func index(at pixelCoordinate: Position2i) -> Index {
116+
func index(for pixelCoordinate: Position2i) -> Index {
73117
return ((self.imageSize.width * pixelCoordinate.y) + pixelCoordinate.x)
74118
}
75119
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright © 2025 Dustin Collins (Strega's Gate)
3+
* All Rights Reserved.
4+
*
5+
* http://stregasgate.com
6+
*/
7+
8+
import XCTest
9+
@testable import GateEngine
10+
11+
@MainActor
12+
final class RawTextureTests: GateEngineXCTestCase {
13+
func testInt() {
14+
let expectedSize = Size2i(width: 16, height: 16)
15+
let rawTexture = RawTexture(imageSize: expectedSize)
16+
XCTAssertEqual(rawTexture.imageSize, expectedSize)
17+
XCTAssertEqual(rawTexture.count, expectedSize.width * expectedSize.height)
18+
}
19+
20+
func testColorAtIndex() {
21+
let expectedSize = Size2i(width: 16, height: 16)
22+
var rawTexture = RawTexture(imageSize: expectedSize)
23+
let index = 24
24+
25+
let color = Color(eightBitRed: 15, green: 30, blue: 45, alpha: 50)
26+
rawTexture.setColor(color, at: index)
27+
XCTAssertEqual(rawTexture.color(at: index), color)
28+
}
29+
30+
func testPixelCoord() {
31+
let expectedSize = Size2i(width: 16, height: 16)
32+
let rawTexture = RawTexture(imageSize: expectedSize)
33+
var expectedIndex = 0
34+
for y in 0 ..< rawTexture.imageSize.height {
35+
for x in 0 ..< rawTexture.imageSize.width {
36+
let pixelCoord = Position2i(x: x, y: y)
37+
let index = rawTexture.index(for: pixelCoord)
38+
XCTAssertEqual(index, expectedIndex)
39+
expectedIndex += 1
40+
}
41+
}
42+
}
43+
44+
func testTextureCoord() {
45+
let expectedSize = Size2i(width: 16, height: 16)
46+
let rawTexture = RawTexture(imageSize: expectedSize)
47+
let pixelSize: Size2f = Size2f.one / Size2f(expectedSize)
48+
let halfSize: Size2f = pixelSize / 2
49+
var expectedIndex = 0
50+
for y in 0 ..< rawTexture.imageSize.height {
51+
for x in 0 ..< rawTexture.imageSize.width {
52+
let pixelCoord = Position2i(x: x, y: y)
53+
let textureCoord: Position2f = Position2f(pixelSize * Position2f(pixelCoord)) + halfSize
54+
55+
let index = rawTexture.index(for: textureCoord)
56+
XCTAssertEqual(index, expectedIndex)
57+
expectedIndex += 1
58+
}
59+
}
60+
}
61+
62+
func testSwapAt() {
63+
let expectedSize = Size2i(width: 16, height: 16)
64+
var rawTexture = RawTexture(imageSize: expectedSize)
65+
66+
let color1 = Color(eightBitRed: 15, green: 30, blue: 45, alpha: 50)
67+
rawTexture.setColor(color1, at: 24)
68+
69+
let color2 = Color(eightBitRed: 16, green: 31, blue: 46, alpha: 51)
70+
rawTexture.setColor(color2, at: 55)
71+
72+
rawTexture.swapAt(24, 55)
73+
74+
XCTAssertEqual(rawTexture.color(at: 24), color2)
75+
XCTAssertEqual(rawTexture.color(at: 55), color1)
76+
}
77+
}

0 commit comments

Comments
 (0)