initial commit
This commit is contained in:
commit
6d27a8ed3a
17 changed files with 4440 additions and 0 deletions
103
Sources/RendererAPI/AudioProtocol.swift
Normal file
103
Sources/RendererAPI/AudioProtocol.swift
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/// Audio System Protocol - Platform-agnostic audio handling
|
||||
/// This module contains ONLY protocol definitions with no platform-specific imports
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Audio Types
|
||||
|
||||
/// Audio source handle
|
||||
public struct AudioHandle: Hashable, Sendable {
|
||||
public let id: UUID
|
||||
public init(id: UUID = UUID()) { self.id = id }
|
||||
}
|
||||
|
||||
/// Audio configuration
|
||||
public struct AudioConfig: Sendable {
|
||||
public var sampleRate: Int
|
||||
public var channels: Int
|
||||
public var bufferSize: Int
|
||||
|
||||
public init(sampleRate: Int = 44100, channels: Int = 2, bufferSize: Int = 4096) {
|
||||
self.sampleRate = sampleRate
|
||||
self.channels = channels
|
||||
self.bufferSize = bufferSize
|
||||
}
|
||||
}
|
||||
|
||||
/// 3D audio source properties
|
||||
public struct AudioSource3D: Sendable {
|
||||
public var position: SIMD3<Float>
|
||||
public var velocity: SIMD3<Float>
|
||||
public var volume: Float
|
||||
public var pitch: Float
|
||||
public var looping: Bool
|
||||
public var spatialize: Bool
|
||||
|
||||
public init(position: SIMD3<Float> = .zero, velocity: SIMD3<Float> = .zero,
|
||||
volume: Float = 1.0, pitch: Float = 1.0, looping: Bool = false, spatialize: Bool = true) {
|
||||
self.position = position
|
||||
self.velocity = velocity
|
||||
self.volume = volume
|
||||
self.pitch = pitch
|
||||
self.looping = looping
|
||||
self.spatialize = spatialize
|
||||
}
|
||||
}
|
||||
|
||||
/// Audio listener properties (typically the camera)
|
||||
public struct AudioListener: Sendable {
|
||||
public var position: SIMD3<Float>
|
||||
public var velocity: SIMD3<Float>
|
||||
public var forward: SIMD3<Float>
|
||||
public var up: SIMD3<Float>
|
||||
|
||||
public init(position: SIMD3<Float> = .zero, velocity: SIMD3<Float> = .zero,
|
||||
forward: SIMD3<Float> = SIMD3<Float>(0, 0, -1), up: SIMD3<Float> = SIMD3<Float>(0, 1, 0)) {
|
||||
self.position = position
|
||||
self.velocity = velocity
|
||||
self.forward = forward
|
||||
self.up = up
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Audio Engine Protocol
|
||||
|
||||
/// Audio system abstraction - all platform-specific audio implementations must conform
|
||||
public protocol AudioEngine: Sendable {
|
||||
/// Initialize the audio system
|
||||
func initialize(config: AudioConfig) async throws
|
||||
|
||||
/// Load an audio clip from file
|
||||
func loadAudio(path: String) async throws -> AudioHandle
|
||||
|
||||
/// Load audio from raw PCM data
|
||||
func loadAudioFromData(data: Data, sampleRate: Int, channels: Int) async throws -> AudioHandle
|
||||
|
||||
/// Play an audio source
|
||||
func play(handle: AudioHandle, source: AudioSource3D) throws
|
||||
|
||||
/// Stop an audio source
|
||||
func stop(handle: AudioHandle) throws
|
||||
|
||||
/// Pause an audio source
|
||||
func pause(handle: AudioHandle) throws
|
||||
|
||||
/// Resume a paused audio source
|
||||
func resume(handle: AudioHandle) throws
|
||||
|
||||
/// Update audio source properties
|
||||
func updateSource(handle: AudioHandle, source: AudioSource3D) throws
|
||||
|
||||
/// Set listener properties (camera/player position)
|
||||
func setListener(listener: AudioListener) throws
|
||||
|
||||
/// Set master volume
|
||||
func setMasterVolume(_ volume: Float) throws
|
||||
|
||||
/// Update audio system (called each frame)
|
||||
func update(deltaTime: Float) throws
|
||||
|
||||
/// Shutdown the audio system
|
||||
func shutdown() async
|
||||
}
|
||||
|
||||
125
Sources/RendererAPI/InputProtocol.swift
Normal file
125
Sources/RendererAPI/InputProtocol.swift
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/// Input System Protocol - Platform-agnostic input handling
|
||||
/// This module contains ONLY protocol definitions with no platform-specific imports
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Input Types
|
||||
|
||||
/// Keyboard key codes
|
||||
public enum KeyCode: Int, Sendable {
|
||||
case unknown = 0
|
||||
case space = 32
|
||||
case apostrophe = 39
|
||||
case comma = 44
|
||||
case minus = 45
|
||||
case period = 46
|
||||
case slash = 47
|
||||
case key0 = 48, key1, key2, key3, key4, key5, key6, key7, key8, key9
|
||||
case semicolon = 59
|
||||
case equal = 61
|
||||
case a = 65, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
|
||||
case leftBracket = 91
|
||||
case backslash = 92
|
||||
case rightBracket = 93
|
||||
case graveAccent = 96
|
||||
case escape = 256
|
||||
case enter = 257
|
||||
case tab = 258
|
||||
case backspace = 259
|
||||
case insert = 260
|
||||
case delete = 261
|
||||
case right = 262
|
||||
case left = 263
|
||||
case down = 264
|
||||
case up = 265
|
||||
case pageUp = 266
|
||||
case pageDown = 267
|
||||
case home = 268
|
||||
case end = 269
|
||||
case capsLock = 280
|
||||
case scrollLock = 281
|
||||
case numLock = 282
|
||||
case printScreen = 283
|
||||
case pause = 284
|
||||
case f1 = 290, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12
|
||||
case leftShift = 340
|
||||
case leftControl = 341
|
||||
case leftAlt = 342
|
||||
case leftSuper = 343
|
||||
case rightShift = 344
|
||||
case rightControl = 345
|
||||
case rightAlt = 346
|
||||
case rightSuper = 347
|
||||
}
|
||||
|
||||
/// Mouse button codes
|
||||
public enum MouseButton: Int, Sendable {
|
||||
case left = 0
|
||||
case right = 1
|
||||
case middle = 2
|
||||
case button4 = 3
|
||||
case button5 = 4
|
||||
}
|
||||
|
||||
/// Input action state
|
||||
public enum InputAction: Sendable {
|
||||
case press
|
||||
case release
|
||||
case repeat_
|
||||
}
|
||||
|
||||
/// Input event types
|
||||
public enum InputEvent: Sendable {
|
||||
case keyEvent(key: KeyCode, action: InputAction)
|
||||
case mouseButton(button: MouseButton, action: InputAction)
|
||||
case mouseMove(x: Double, y: Double)
|
||||
case mouseScroll(xOffset: Double, yOffset: Double)
|
||||
case gamepadButton(gamepadId: Int, button: Int, action: InputAction)
|
||||
case gamepadAxis(gamepadId: Int, axis: Int, value: Float)
|
||||
}
|
||||
|
||||
// MARK: - Input Handler Protocol
|
||||
|
||||
/// Input system abstraction - all platform-specific input implementations must conform
|
||||
public protocol InputHandler: Sendable {
|
||||
/// Initialize the input system
|
||||
func initialize() async throws
|
||||
|
||||
/// Poll for input events (called each frame)
|
||||
func pollEvents() -> [InputEvent]
|
||||
|
||||
/// Check if a key is currently pressed
|
||||
func isKeyPressed(_ key: KeyCode) -> Bool
|
||||
|
||||
/// Check if a mouse button is currently pressed
|
||||
func isMouseButtonPressed(_ button: MouseButton) -> Bool
|
||||
|
||||
/// Get current mouse position
|
||||
func getMousePosition() -> (x: Double, y: Double)
|
||||
|
||||
/// Set mouse cursor visibility
|
||||
func setCursorVisible(_ visible: Bool)
|
||||
|
||||
/// Set mouse cursor mode (normal, hidden, locked)
|
||||
func setCursorMode(_ mode: CursorMode)
|
||||
|
||||
/// Get connected gamepad count
|
||||
func getGamepadCount() -> Int
|
||||
|
||||
/// Check if a gamepad is connected
|
||||
func isGamepadConnected(_ gamepadId: Int) -> Bool
|
||||
|
||||
/// Get gamepad name
|
||||
func getGamepadName(_ gamepadId: Int) -> String?
|
||||
|
||||
/// Shutdown the input system
|
||||
func shutdown() async
|
||||
}
|
||||
|
||||
/// Cursor display mode
|
||||
public enum CursorMode: Sendable {
|
||||
case normal
|
||||
case hidden
|
||||
case locked
|
||||
}
|
||||
|
||||
197
Sources/RendererAPI/RendererProtocol.swift
Normal file
197
Sources/RendererAPI/RendererProtocol.swift
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/// RendererAPI - Protocol Definitions for Platform Abstraction
|
||||
/// This module contains ONLY protocol definitions with no platform-specific imports
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Core Rendering Types
|
||||
|
||||
/// Represents a 3D scene to be rendered
|
||||
public struct Scene {
|
||||
public var entities: [Entity]
|
||||
public var camera: Camera
|
||||
public var lights: [Light]
|
||||
|
||||
public init(entities: [Entity] = [], camera: Camera, lights: [Light] = []) {
|
||||
self.entities = entities
|
||||
self.camera = camera
|
||||
self.lights = lights
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a renderable entity in the scene
|
||||
public struct Entity {
|
||||
public var id: UUID
|
||||
public var transform: Transform
|
||||
public var mesh: MeshHandle
|
||||
public var material: MaterialHandle
|
||||
|
||||
public init(id: UUID = UUID(), transform: Transform, mesh: MeshHandle, material: MaterialHandle) {
|
||||
self.id = id
|
||||
self.transform = transform
|
||||
self.mesh = mesh
|
||||
self.material = material
|
||||
}
|
||||
}
|
||||
|
||||
/// Camera configuration
|
||||
public struct Camera {
|
||||
public var position: SIMD3<Float>
|
||||
public var rotation: SIMD4<Float> // Quaternion
|
||||
public var fieldOfView: Float
|
||||
public var nearPlane: Float
|
||||
public var farPlane: Float
|
||||
|
||||
public init(position: SIMD3<Float> = .zero, rotation: SIMD4<Float> = SIMD4<Float>(0, 0, 0, 1),
|
||||
fieldOfView: Float = 60.0, nearPlane: Float = 0.1, farPlane: Float = 1000.0) {
|
||||
self.position = position
|
||||
self.rotation = rotation
|
||||
self.fieldOfView = fieldOfView
|
||||
self.nearPlane = nearPlane
|
||||
self.farPlane = farPlane
|
||||
}
|
||||
}
|
||||
|
||||
/// Transform component
|
||||
public struct Transform {
|
||||
public var position: SIMD3<Float>
|
||||
public var rotation: SIMD4<Float> // Quaternion
|
||||
public var scale: SIMD3<Float>
|
||||
|
||||
public init(position: SIMD3<Float> = .zero, rotation: SIMD4<Float> = SIMD4<Float>(0, 0, 0, 1),
|
||||
scale: SIMD3<Float> = SIMD3<Float>(1, 1, 1)) {
|
||||
self.position = position
|
||||
self.rotation = rotation
|
||||
self.scale = scale
|
||||
}
|
||||
}
|
||||
|
||||
/// Light source
|
||||
public struct Light {
|
||||
public enum LightType {
|
||||
case directional
|
||||
case point
|
||||
case spot
|
||||
}
|
||||
|
||||
public var type: LightType
|
||||
public var position: SIMD3<Float>
|
||||
public var direction: SIMD3<Float>
|
||||
public var color: SIMD3<Float>
|
||||
public var intensity: Float
|
||||
|
||||
public init(type: LightType, position: SIMD3<Float> = .zero, direction: SIMD3<Float> = SIMD3<Float>(0, -1, 0),
|
||||
color: SIMD3<Float> = SIMD3<Float>(1, 1, 1), intensity: Float = 1.0) {
|
||||
self.type = type
|
||||
self.position = position
|
||||
self.direction = direction
|
||||
self.color = color
|
||||
self.intensity = intensity
|
||||
}
|
||||
}
|
||||
|
||||
/// Opaque handle for mesh resources
|
||||
public struct MeshHandle: Hashable {
|
||||
public let id: UUID
|
||||
public init(id: UUID = UUID()) { self.id = id }
|
||||
}
|
||||
|
||||
/// Opaque handle for material resources
|
||||
public struct MaterialHandle: Hashable {
|
||||
public let id: UUID
|
||||
public init(id: UUID = UUID()) { self.id = id }
|
||||
}
|
||||
|
||||
/// Opaque handle for texture resources
|
||||
public struct TextureHandle: Hashable {
|
||||
public let id: UUID
|
||||
public init(id: UUID = UUID()) { self.id = id }
|
||||
}
|
||||
|
||||
// MARK: - Renderer Protocol
|
||||
|
||||
/// Primary rendering abstraction - all rendering backends must conform to this
|
||||
public protocol Renderer: Sendable {
|
||||
/// Initialize the renderer with the given configuration
|
||||
func initialize(config: RendererConfig) async throws
|
||||
|
||||
/// Begin a new frame
|
||||
func beginFrame() throws
|
||||
|
||||
/// Draw the current scene
|
||||
func draw(scene: Scene) throws
|
||||
|
||||
/// End the current frame and present
|
||||
func endFrame() throws
|
||||
|
||||
/// Shutdown and cleanup resources
|
||||
func shutdown() async
|
||||
|
||||
/// Load a mesh into GPU memory
|
||||
func loadMesh(vertices: [Vertex], indices: [UInt32]) async throws -> MeshHandle
|
||||
|
||||
/// Load a texture into GPU memory
|
||||
func loadTexture(data: Data, width: Int, height: Int, format: TextureFormat) async throws -> TextureHandle
|
||||
|
||||
/// Create a material
|
||||
func createMaterial(albedoTexture: TextureHandle?, normalTexture: TextureHandle?) async throws -> MaterialHandle
|
||||
|
||||
/// Get renderer capabilities and information
|
||||
var info: RendererInfo { get }
|
||||
}
|
||||
|
||||
/// Renderer configuration
|
||||
public struct RendererConfig: Sendable {
|
||||
public var windowHandle: UnsafeMutableRawPointer?
|
||||
public var width: Int
|
||||
public var height: Int
|
||||
public var vsyncEnabled: Bool
|
||||
public var msaaSamples: Int
|
||||
|
||||
public init(windowHandle: UnsafeMutableRawPointer? = nil, width: Int = 1920, height: Int = 1080,
|
||||
vsyncEnabled: Bool = true, msaaSamples: Int = 4) {
|
||||
self.windowHandle = windowHandle
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.vsyncEnabled = vsyncEnabled
|
||||
self.msaaSamples = msaaSamples
|
||||
}
|
||||
}
|
||||
|
||||
/// Renderer information
|
||||
public struct RendererInfo: Sendable {
|
||||
public var apiName: String
|
||||
public var apiVersion: String
|
||||
public var deviceName: String
|
||||
public var maxTextureSize: Int
|
||||
|
||||
public init(apiName: String, apiVersion: String, deviceName: String, maxTextureSize: Int) {
|
||||
self.apiName = apiName
|
||||
self.apiVersion = apiVersion
|
||||
self.deviceName = deviceName
|
||||
self.maxTextureSize = maxTextureSize
|
||||
}
|
||||
}
|
||||
|
||||
/// Vertex data structure
|
||||
public struct Vertex: Sendable {
|
||||
public var position: SIMD3<Float>
|
||||
public var normal: SIMD3<Float>
|
||||
public var uv: SIMD2<Float>
|
||||
public var tangent: SIMD3<Float>
|
||||
|
||||
public init(position: SIMD3<Float>, normal: SIMD3<Float>, uv: SIMD2<Float>, tangent: SIMD3<Float> = .zero) {
|
||||
self.position = position
|
||||
self.normal = normal
|
||||
self.uv = uv
|
||||
self.tangent = tangent
|
||||
}
|
||||
}
|
||||
|
||||
/// Texture format enumeration
|
||||
public enum TextureFormat: Sendable {
|
||||
case rgba8
|
||||
case rgba16f
|
||||
case rgba32f
|
||||
case depth24stencil8
|
||||
}
|
||||
|
||||
72
Sources/RendererAPI/WindowProtocol.swift
Normal file
72
Sources/RendererAPI/WindowProtocol.swift
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/// Window Management Protocol - Platform-agnostic window handling
|
||||
/// This module contains ONLY protocol definitions with no platform-specific imports
|
||||
|
||||
import Foundation
|
||||
|
||||
// MARK: - Window Types
|
||||
|
||||
/// Window configuration
|
||||
public struct WindowConfig: Sendable {
|
||||
public var title: String
|
||||
public var width: Int
|
||||
public var height: Int
|
||||
public var fullscreen: Bool
|
||||
public var resizable: Bool
|
||||
public var vsyncEnabled: Bool
|
||||
|
||||
public init(title: String = "SportsBallEngine", width: Int = 1920, height: Int = 1080,
|
||||
fullscreen: Bool = false, resizable: Bool = true, vsyncEnabled: Bool = true) {
|
||||
self.title = title
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.fullscreen = fullscreen
|
||||
self.resizable = resizable
|
||||
self.vsyncEnabled = vsyncEnabled
|
||||
}
|
||||
}
|
||||
|
||||
/// Window event types
|
||||
public enum WindowEvent: Sendable {
|
||||
case close
|
||||
case resize(width: Int, height: Int)
|
||||
case focus(focused: Bool)
|
||||
case minimize
|
||||
case maximize
|
||||
case restore
|
||||
}
|
||||
|
||||
// MARK: - Window Manager Protocol
|
||||
|
||||
/// Window system abstraction - all platform-specific window implementations must conform
|
||||
public protocol WindowManager: Sendable {
|
||||
/// Create and initialize a window with the given configuration
|
||||
func createWindow(config: WindowConfig) async throws
|
||||
|
||||
/// Check if the window should close
|
||||
func shouldClose() -> Bool
|
||||
|
||||
/// Process window events (called each frame)
|
||||
func processEvents() -> [WindowEvent]
|
||||
|
||||
/// Get current window size
|
||||
func getSize() -> (width: Int, height: Int)
|
||||
|
||||
/// Set window size
|
||||
func setSize(width: Int, height: Int) throws
|
||||
|
||||
/// Set window title
|
||||
func setTitle(_ title: String) throws
|
||||
|
||||
/// Toggle fullscreen mode
|
||||
func setFullscreen(_ fullscreen: Bool) throws
|
||||
|
||||
/// Get native window handle (for renderer initialization)
|
||||
func getNativeHandle() -> UnsafeMutableRawPointer?
|
||||
|
||||
/// Swap buffers / present frame
|
||||
func swapBuffers() throws
|
||||
|
||||
/// Destroy the window and cleanup
|
||||
func destroyWindow() async
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue