The Skung Rockification of Ziggy Skungdust and the SIMD's
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
//#set OPENGL3
|
||||
|
||||
import Foundation
|
||||
import Maths
|
||||
import SDL2
|
||||
#if OPENGL3
|
||||
import OpenGL
|
||||
#if OPENGL3
|
||||
import OpenGL.GL
|
||||
#else
|
||||
import OpenGL.GL3
|
||||
#endif
|
||||
@ -41,7 +43,7 @@ class OpenGL: Renderer
|
||||
guard SDL_GL_MakeCurrent(sdlWindow, glCtx) == 0
|
||||
else { throw RendererError.sdlError(message: "SDL_GL_MakeCurrent: \(String(cString: SDL_GetError()))") }
|
||||
|
||||
state.enable([.texture2D, .cullFace, .depthTest, .rescaleNormal, .colourMaterial])
|
||||
state.enable([.texture2D, .cullFace, .depthTest, .rescaleNormal/*, .colourMaterial */])
|
||||
if srgb { state.enable(.frameBufferSrgb) }
|
||||
state.cullFace = .back
|
||||
state.clearDepth = 1
|
||||
@ -132,13 +134,12 @@ class OpenGL: Renderer
|
||||
materials: mesh.materials)
|
||||
}
|
||||
|
||||
func createTexture(data: UnsafeRawPointer, width: Int, height: Int) throws -> RenderTexture2D
|
||||
func createTexture(image: Image) throws -> RenderTexture2D
|
||||
{
|
||||
try createTexture(data: data, width: width, height: height, filter: .linear, mipMode: .off)
|
||||
try createTexture(image: image, filter: .linear, mipMode: .off)
|
||||
}
|
||||
|
||||
func createTexture(data: UnsafeRawPointer, width: Int, height: Int,
|
||||
filter: FilterMode, mipMode: MipMode) throws -> RenderTexture2D
|
||||
func createTexture(image: Image, filter: FilterMode, mipMode: MipMode) throws -> RenderTexture2D
|
||||
{
|
||||
let min: Int32 = switch mipMode
|
||||
{
|
||||
@ -146,14 +147,19 @@ class OpenGL: Renderer
|
||||
case .nearest: filter.glMip
|
||||
case .linear: filter.glLinearMip
|
||||
}
|
||||
return RenderTexture2D(try loadTexture(data: data,
|
||||
width: GLsizei(width), height: GLsizei(height),
|
||||
minFilter: min, magFilter: filter.gl))
|
||||
return try image.data.withUnsafeBytes
|
||||
{ raw in
|
||||
RenderTexture2D(try loadTexture(
|
||||
data: raw.baseAddress!, format: image.format,
|
||||
width: GLsizei(image.width), height: GLsizei(image.height),
|
||||
mipLevels: image.mipLevels,
|
||||
minFilter: min, magFilter: filter.gl))
|
||||
}
|
||||
}
|
||||
|
||||
private func loadTexture(
|
||||
data: UnsafeRawPointer,
|
||||
width: GLsizei, height: GLsizei,
|
||||
data: UnsafeRawPointer, format: Image.Format,
|
||||
width: GLsizei, height: GLsizei, mipLevels: Int,
|
||||
minFilter: Int32 = GL_LINEAR, magFilter: Int32 = GL_LINEAR,
|
||||
wrap: Int32 = GL_REPEAT) throws -> GLuint
|
||||
{
|
||||
@ -165,19 +171,49 @@ class OpenGL: Renderer
|
||||
state.texture2DParameter(active: 0, param: .magFilter, int: magFilter)
|
||||
state.texture2DParameter(active: 0, param: .wrapS, int: wrap)
|
||||
state.texture2DParameter(active: 0, param: .wrapT, int: wrap)
|
||||
let format: GLint = srgb ? GL_SRGB8 : GL_RGBA
|
||||
glTexImage2D(GLenum(GL_TEXTURE_2D),
|
||||
0, format, width, height, 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), data)
|
||||
|
||||
let upload = getTextureUploader(format: format)
|
||||
var offset = 0
|
||||
for i in 0...mipLevels
|
||||
{
|
||||
let levelWidth = width &>> i, levelHeight = height &>> i
|
||||
let size = format.computeSize(width: UInt32(levelWidth), height: UInt32(levelHeight))
|
||||
upload(GLint(i), levelWidth, levelHeight, data + offset, GLsizei(size))
|
||||
offset += size
|
||||
}
|
||||
|
||||
// Generate mipmaps if needed
|
||||
if [GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST]
|
||||
.contains(minFilter) { glGenerateMipmap(GLenum(GL_TEXTURE_2D)) }
|
||||
.contains(minFilter) && mipLevels == 0 { glGenerateMipmap(GLenum(GL_TEXTURE_2D)) }
|
||||
|
||||
state.bindTexture2D(active: 0, texture: OpenGLState.defaultTexture)
|
||||
|
||||
return texId
|
||||
}
|
||||
|
||||
private typealias UploadFunc = (GLint, GLsizei, GLsizei, UnsafeRawPointer, GLsizei) -> Void
|
||||
private func getTextureUploader(format: Image.Format) -> UploadFunc
|
||||
{
|
||||
let target = GLenum(GL_TEXTURE_2D)
|
||||
let border: GLint = 0
|
||||
return switch format
|
||||
{
|
||||
case .argb8888: { (level, width, height, data, size) in
|
||||
glTexImage2D(target, level, GLint(self.srgb ? GL_SRGB8 : GL_RGBA),
|
||||
width, height, border, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), data)
|
||||
}
|
||||
case .s3tc_bc1: { (level, width, height, data, size) in
|
||||
glCompressedTexImage2D(target, level, GLenum(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT),
|
||||
width, height, border, size, data)
|
||||
}
|
||||
case .rgtc_bc5_3dc: { (level, width, height, data, size) in
|
||||
glCompressedTexImage2D(target, level, GLenum(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT),
|
||||
width, height, border, size, data)
|
||||
}
|
||||
default: fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func deleteMesh<V: Vertex>(_ mesh: RenderMesh<V>)
|
||||
{
|
||||
@ -210,7 +246,11 @@ class OpenGL: Renderer
|
||||
|
||||
func setMaterial(_ mat: Material)
|
||||
{
|
||||
glColor4f(mat.diffuse.r, mat.diffuse.g, mat.diffuse.b, mat.diffuse.a)
|
||||
//glColor4f(mat.diffuse.r, mat.diffuse.g, mat.diffuse.b, mat.diffuse.a)
|
||||
state.materialDiffuse = srgb ? mat.diffuse.linear : mat.diffuse
|
||||
state.materialSpecular = srgb ? mat.specular.linear : mat.specular
|
||||
state.materialEmmision = srgb ? mat.emmision.linear : mat.emmision
|
||||
state.materialShininess = mat.specularExp
|
||||
state.bindTexture2D(active: 0, texture: mat.texture.isValid ? mat.texture.id : 0)
|
||||
}
|
||||
|
||||
@ -226,14 +266,13 @@ class OpenGL: Renderer
|
||||
|
||||
private func bindMesh<V: Vertex>(mesh: RenderMesh<V>)
|
||||
{
|
||||
state.enableClient([ .vertex, .colour, .normal, .textureCoord ])
|
||||
|
||||
state.arrayBuffer = UInt32(mesh.vboHnd)
|
||||
state.elementArrayBuffer = UInt32(mesh.iboHnd)
|
||||
|
||||
let stride = GLsizei(MemoryLayout<V>.stride)
|
||||
if V.self == VertexPositionNormalTexcoord.self
|
||||
{
|
||||
state.enableClient([ .vertex, .normal, .textureCoord ])
|
||||
glVertexPointer(3, GLenum(GL_FLOAT), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalTexcoord.position)!))
|
||||
glNormalPointer(GLenum(GL_FLOAT), stride,
|
||||
@ -243,6 +282,7 @@ class OpenGL: Renderer
|
||||
}
|
||||
else if V.self == VertexPositionNormalColourTexcoord.self
|
||||
{
|
||||
state.enableClient([ .vertex, .colour, .normal, .textureCoord ])
|
||||
glVertexPointer(3, GLenum(GL_FLOAT), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.position)!))
|
||||
glColorPointer(4, GLenum(GL_FLOAT), stride,
|
||||
@ -252,6 +292,16 @@ class OpenGL: Renderer
|
||||
glTexCoordPointer(2, GLenum(GL_FLOAT), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VertexPositionNormalColourTexcoord.texCoord)!))
|
||||
}
|
||||
else if V.self == VMeshVertex.self
|
||||
{
|
||||
state.enableClient([ .vertex, .normal, .textureCoord ])
|
||||
glVertexPointer(3, GLenum(GL_FLOAT), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VMeshVertex.position)!))
|
||||
glTexCoordPointer(2, GLenum(GL_FLOAT), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VMeshVertex.texCoord)!))
|
||||
glNormalPointer(GLenum(GL_BYTE), stride,
|
||||
UnsafeRawPointer.init(bitPattern: MemoryLayout.offset(of: \VMeshVertex.normal)!))
|
||||
}
|
||||
}
|
||||
|
||||
private func unbindMesh()
|
||||
@ -259,7 +309,7 @@ class OpenGL: Renderer
|
||||
state.elementArrayBuffer = OpenGLState.defaultBuffer
|
||||
state.arrayBuffer = OpenGLState.defaultBuffer
|
||||
|
||||
state.disableClient([ .vertex, .normal, .textureCoord ])
|
||||
state.disableClient([ .vertex, .colour, .normal, .textureCoord ])
|
||||
}
|
||||
|
||||
private func draw<V: Vertex>(mesh: RenderMesh<V>)
|
||||
@ -302,7 +352,8 @@ class OpenGL: Renderer
|
||||
|
||||
private func loadMatrix(_ matrix: Mat4f)
|
||||
{
|
||||
withUnsafePointer(to: matrix.columns)
|
||||
//withUnsafePointer(to: matrix.columns)
|
||||
withUnsafePointer(to: matrix)
|
||||
{
|
||||
$0.withMemoryRebound(to: GLfloat.self, capacity: 16)
|
||||
{ (values: UnsafePointer<GLfloat>) in
|
||||
@ -313,7 +364,8 @@ class OpenGL: Renderer
|
||||
|
||||
private func mulMatrix(_ matrix: Mat4f)
|
||||
{
|
||||
withUnsafePointer(to: matrix.columns)
|
||||
//withUnsafePointer(to: matrix.columns)
|
||||
withUnsafePointer(to: matrix)
|
||||
{
|
||||
$0.withMemoryRebound(to: GLfloat.self, capacity: 16)
|
||||
{ (values: UnsafePointer<GLfloat>) in
|
||||
@ -360,6 +412,7 @@ class OpenGL: Renderer
|
||||
}
|
||||
|
||||
state.lightModelAmbient = env.ambient
|
||||
state.lightModelLocalViewer = true
|
||||
|
||||
let lightCaps: [OpenGLState.Capability] = [
|
||||
.light0, .light1, .light2, .light3,
|
||||
|
Reference in New Issue
Block a user