The Skung Cave commit

This commit is contained in:
2024-05-09 20:52:01 +10:00
parent 446c444728
commit 06046cd163
36 changed files with 11988 additions and 9252 deletions

View File

@ -76,13 +76,19 @@ class OpenGL: Renderer
}
}
var wireframe: Bool
{
get { state.polygonMode == .line }
set(mode) { state.polygonMode = mode ? .line : .fill }
}
func setVsync(mode: VSyncMode) throws
{
guard SDL_GL_SetSwapInterval(mode.sdlInterval) == 0
else { throw RendererError.sdlError(message: "SDL_GL_SetSwapInterval: \(String(cString: SDL_GetError()))") }
}
func createMesh(mesh: Mesh) throws -> RenderMesh
func createMesh<V: Vertex>(mesh: Mesh<V>) throws -> RenderMesh<V>
{
var buffers = [GLuint](repeating: 0, count: 2)
buffers.withUnsafeMutableBufferPointer
@ -94,35 +100,36 @@ class OpenGL: Renderer
state.elementArrayBuffer = buffers[1]
glBufferData(GLenum(GL_ARRAY_BUFFER),
MemoryLayout<Mesh.Vertex>.stride * mesh.vertices.count,
MemoryLayout<V>.stride * mesh.vertices.count,
mesh.vertices, GLenum(GL_STATIC_DRAW))
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER),
MemoryLayout<Mesh.Index>.stride * mesh.indices.count,
MemoryLayout<V>.stride * mesh.indices.count,
mesh.indices, GLenum(GL_STATIC_DRAW))
state.elementArrayBuffer = OpenGLState.defaultBuffer
state.arrayBuffer = OpenGLState.defaultBuffer
var subMeshes = [Mesh.SubMesh]()
var subMeshes = [Mesh<V>.SubMesh]()
if mesh.subMeshes.isEmpty
{
subMeshes.append(Mesh.SubMesh(start: 0, length: mesh.indices.count))
subMeshes.append(Mesh<V>.SubMesh(start: 0, length: mesh.indices.count))
}
else
{
for subMesh in mesh.subMeshes
{
if ["Collision", "Collision3D"].contains(subMesh.key) { continue }
subMeshes.append(Mesh.SubMesh(
subMeshes.append(Mesh<V>.SubMesh(
start: subMesh.value.start,
length: subMesh.value.length))
length: subMesh.value.length,
material: subMesh.value.material))
}
}
return RenderMesh(
vbo: Int(buffers[0]),
ibo: Int(buffers[1]),
subMeshes: subMeshes)
subMeshes: subMeshes,
materials: mesh.materials)
}
func createTexture(data: UnsafeRawPointer, width: Int, height: Int) throws -> RenderTexture2D
@ -172,7 +179,7 @@ class OpenGL: Renderer
}
func deleteMesh(_ mesh: RenderMesh)
func deleteMesh<V: Vertex>(_ mesh: RenderMesh<V>)
{
var buffers = [GLuint](repeating: 0, count: 2)
buffers[0] = GLuint(mesh.iboHnd)
@ -208,42 +215,64 @@ class OpenGL: Renderer
}
private func draw(subMesh: Mesh.SubMesh)
private func draw<V: Vertex>(subMesh: Mesh<V>.SubMesh)
{
glDrawElements(
GLenum(GL_TRIANGLES),
GLsizei(subMesh.length),
GLenum(GL_UNSIGNED_SHORT),
.init(bitPattern: MemoryLayout<Mesh.Index>.stride * subMesh.start));
.init(bitPattern: MemoryLayout<Mesh<V>.Index>.stride * subMesh.start));
}
private func draw(mesh: RenderMesh)
private func bindMesh<V: Vertex>(mesh: RenderMesh<V>)
{
state.enableClient([ .vertex, .normal, .textureCoord ])
state.enableClient([ .vertex, .colour, .normal, .textureCoord ])
state.arrayBuffer = UInt32(mesh.vboHnd)
state.elementArrayBuffer = UInt32(mesh.iboHnd)
let stride = GLsizei(MemoryLayout<Mesh.Vertex>.stride)
glVertexPointer(3, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \Mesh.Vertex.position)!))
glNormalPointer(GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \Mesh.Vertex.normal)!))
glTexCoordPointer(2, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \Mesh.Vertex.texCoord)!))
for subMesh in mesh.subMeshes
let stride = GLsizei(MemoryLayout<V>.stride)
if V.self == VertexPositionNormalTexcoord.self
{
draw(subMesh: subMesh)
glVertexPointer(3, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalTexcoord.position)!))
glNormalPointer(GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalTexcoord.normal)!))
glTexCoordPointer(2, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalTexcoord.texCoord)!))
}
else if V.self == VertexPositionNormalColourTexcoord.self
{
glVertexPointer(3, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.position)!))
glColorPointer(4, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.colour)!))
glNormalPointer(GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.normal)!))
glTexCoordPointer(2, GLenum(GL_FLOAT), stride,
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.texCoord)!))
}
}
private func unbindMesh()
{
state.elementArrayBuffer = OpenGLState.defaultBuffer
state.arrayBuffer = OpenGLState.defaultBuffer
state.disableClient([ .vertex, .normal, .textureCoord ])
}
func draw(mesh: RenderMesh, model: Mat4f, environment env: Environment)
private func draw<V: Vertex>(mesh: RenderMesh<V>)
{
bindMesh(mesh: mesh)
for subMesh in mesh.subMeshes
{
draw(subMesh: subMesh)
}
unbindMesh()
}
func draw<V: Vertex>(mesh: RenderMesh<V>, model: Mat4f, environment env: Environment)
{
if (mesh.subMeshes.isEmpty) { return }
@ -255,7 +284,7 @@ class OpenGL: Renderer
glPopMatrix()
}
func draw(mesh: RenderMesh, environment env: Environment)
func draw<V: Vertex>(mesh: RenderMesh<V>, environment env: Environment)
{
if (mesh.subMeshes.isEmpty) { return }
@ -263,6 +292,14 @@ class OpenGL: Renderer
draw(mesh: mesh)
}
func draw<V: Vertex>(mesh: RenderMesh<V>, subMesh: Mesh<V>.SubMesh, environment env: Environment)
{
applyEnvironment(env)
bindMesh(mesh: mesh)
draw(subMesh: subMesh)
unbindMesh()
}
private func loadMatrix(_ matrix: Mat4f)
{
withUnsafePointer(to: matrix.columns)

View File

@ -793,4 +793,26 @@ struct OpenGLState
}
}
}
enum PolygonMode { case point, line, fill }
private var _polygonMode = PolygonMode.fill
var polygonMode: PolygonMode
{
get { _polygonMode }
set(newMode)
{
if newMode != _polygonMode
{
let modeEnum = switch newMode
{
case .point: GL_POINT
case .line: GL_LINE
case .fill: GL_FILL
}
glPolygonMode(GLenum(GL_FRONT_AND_BACK), GLenum(modeEnum));
_polygonMode = newMode
}
}
}
}

View File

@ -11,15 +11,16 @@ public protocol Renderer
func resize(width: Int32, height: Int32)
var clearColour: Colour { get set }
var wireframe: Bool { get set }
func setVsync(mode: VSyncMode) throws
func createMesh(mesh: Mesh) throws -> RenderMesh
func createMesh<V: Vertex>(mesh: Mesh<V>) throws -> RenderMesh<V>
func createTexture(data: UnsafeRawPointer, width: Int, height: Int) throws -> RenderTexture2D
func createTexture(data: UnsafeRawPointer, width: Int, height: Int,
filter: FilterMode, mipMode: MipMode) throws -> RenderTexture2D
func deleteMesh(_ mesh: RenderMesh)
func deleteMesh<V: Vertex>(_ mesh: RenderMesh<V>)
func deleteTexture(_ texture: RenderTexture2D)
func setProjection(matrix: Mat4f)
@ -27,8 +28,9 @@ public protocol Renderer
func setMaterial(_ mat: Material)
func draw(mesh: RenderMesh, model: Mat4f, environment: Environment)
func draw(mesh: RenderMesh, environment: Environment)
func draw<V: Vertex>(mesh: RenderMesh<V>, model: Mat4f, environment: Environment)
func draw<V: Vertex>(mesh: RenderMesh<V>, environment: Environment)
func draw<V: Vertex>(mesh: RenderMesh<V>, subMesh: Mesh<V>.SubMesh, environment: Environment)
func drawGizmos(lines: [Line])
}
@ -76,9 +78,9 @@ public protocol RendererResource
var isValid: Bool { get }
}
public struct RenderMesh: RendererResource
public struct RenderMesh<V: Vertex>: RendererResource
{
public typealias T = Mesh
public typealias T = Mesh<V>
public static var empty: RenderMesh { .init() }
@ -86,7 +88,8 @@ public struct RenderMesh: RendererResource
private let _valid: Bool;
let vboHnd: Int, iboHnd: Int
let subMeshes: [Mesh.SubMesh]
public let subMeshes: [Mesh<V>.SubMesh]
public let materials: [Material] // HACK !!!!
private init()
{
@ -94,14 +97,16 @@ public struct RenderMesh: RendererResource
self.vboHnd = 0
self.iboHnd = 0
self.subMeshes = []
self.materials = []
}
init(vbo: Int, ibo: Int, subMeshes: [Mesh.SubMesh])
init(vbo: Int, ibo: Int, subMeshes: [Mesh<V>.SubMesh], materials: [Material] = .init())
{
self._valid = true
self.vboHnd = vbo
self.iboHnd = ibo
self.subMeshes = subMeshes
self.materials = materials
}
}