Compare commits
3 commits
60c7cedb24
...
2dccf140b1
Author | SHA1 | Date | |
---|---|---|---|
2dccf140b1 | |||
764353372e | |||
9a434e1733 |
16 changed files with 143 additions and 105 deletions
12
.gitmodules
vendored
12
.gitmodules
vendored
|
@ -1,9 +1,15 @@
|
||||||
[submodule "libs/vmath"]
|
[submodule "libs/vmath"]
|
||||||
path = libs/vmath
|
path = libs/vmath
|
||||||
url = https://git.myou.dev/MyouProject/vmath
|
url = https://git.myou.dev/MyouProject/vmath
|
||||||
[submodule "libs/pixie"]
|
|
||||||
path = libs/pixie
|
|
||||||
url = https://git.myou.dev/MyouProject/pixie
|
|
||||||
[submodule "libs/nim_zstd"]
|
[submodule "libs/nim_zstd"]
|
||||||
path = libs/nim_zstd
|
path = libs/nim_zstd
|
||||||
url = https://github.com/DiThi/nim_zstd
|
url = https://github.com/DiThi/nim_zstd
|
||||||
|
[submodule "libs/stb_image_nim"]
|
||||||
|
path = libs/stb_image_nim
|
||||||
|
url = https://gitlab.com/kungfoobar/stb_image-Nim.git
|
||||||
|
[submodule "libs/tinyre"]
|
||||||
|
path = libs/tinyre
|
||||||
|
url = https://github.com/khchen/tinyre
|
||||||
|
[submodule "libs/nglfw"]
|
||||||
|
path = libs/nglfw
|
||||||
|
url = https://github.com/DiThi/nglfw
|
||||||
|
|
1
libs/nglfw
Submodule
1
libs/nglfw
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 4ffed95fde502a86fd694b99e755300984d13ae1
|
|
@ -1,3 +0,0 @@
|
||||||
import ../pixie/src/pixie
|
|
||||||
export pixie
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 84589810078f5b9ca85b510393e0cf1364481e65
|
|
1
libs/stb_image_nim
Submodule
1
libs/stb_image_nim
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 57212e9dccd0bc4506a34101d69c32565eefa8fc
|
1
libs/tinyre
Submodule
1
libs/tinyre
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 77469f58916369bc3863194cabb05238577fb257
|
|
@ -61,7 +61,6 @@ proc use*(self: Shader): GLuint {.inline,discardable.}
|
||||||
proc destroy*(self: Shader)
|
proc destroy*(self: Shader)
|
||||||
# End forward declarations
|
# End forward declarations
|
||||||
|
|
||||||
import elvis
|
|
||||||
import tinyre
|
import tinyre
|
||||||
import std/sequtils
|
import std/sequtils
|
||||||
import std/strformat
|
import std/strformat
|
||||||
|
@ -439,13 +438,13 @@ proc initShader*(self: Shader, engine: MyouEngine, material: Material,
|
||||||
glDeleteShader(fragment_shader)
|
glDeleteShader(fragment_shader)
|
||||||
if "ERROR: 0:" in gl_log:
|
if "ERROR: 0:" in gl_log:
|
||||||
# Show engine for first error
|
# Show engine for first error
|
||||||
let line = error_msg.split(":")[2].parseInt ?: 0
|
let line = try: error_msg.split(":")[2].parseInt except: 0
|
||||||
# TODO: show only 4 lines of engine but also the previous
|
# TODO: show only 4 lines of engine but also the previous
|
||||||
# line without indent to know which function it is
|
# line without indent to know which function it is
|
||||||
for i in max(1, line - 1000) ..< min(line + 4, lines.len):
|
for i in max(1, line - 1000) ..< min(line + 4, lines.len):
|
||||||
console_error(&"{i} {lines[i - 1]}")
|
console_error(&"{i} {lines[i - 1]}")
|
||||||
elif gl_log.startsWith "0(":
|
elif gl_log.startsWith "0(":
|
||||||
let line = error_msg.split({'(',')'})[1].parseInt ?: 0
|
let line = try: error_msg.split({'(',')'})[1].parseInt except: 0
|
||||||
for i in max(1, line - 1000) ..< min(line + 4, lines.len):
|
for i in max(1, line - 1000) ..< min(line + 4, lines.len):
|
||||||
console_error(&"{i} {lines[i - 1]}")
|
console_error(&"{i} {lines[i - 1]}")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -51,7 +51,6 @@ proc draw_cubemap*(self: RenderManager, scene: Scene, cubemap_fb: Framebuffer, c
|
||||||
proc get_render_uniform_blocks*(): string
|
proc get_render_uniform_blocks*(): string
|
||||||
# End forward declarations
|
# End forward declarations
|
||||||
|
|
||||||
import elvis
|
|
||||||
import std/algorithm
|
import std/algorithm
|
||||||
import std/options
|
import std/options
|
||||||
import std/strformat
|
import std/strformat
|
||||||
|
@ -266,7 +265,7 @@ proc draw_mesh*(self: RenderManager, mesh: Mesh, mesh2world: Mat4, cam_data: Ren
|
||||||
continue
|
continue
|
||||||
|
|
||||||
var mat = if material_override == nil:
|
var mat = if material_override == nil:
|
||||||
amesh.materials.get_or_default(submesh_idx) ?: self.no_material
|
amesh.materials.get_or_default(submesh_idx, self.no_material)
|
||||||
else:
|
else:
|
||||||
material_override
|
material_override
|
||||||
|
|
||||||
|
@ -417,7 +416,10 @@ proc draw_quad*(self: RenderManager, material: Material, scene: Scene, cam_data:
|
||||||
|
|
||||||
proc draw_viewport*(self: RenderManager, viewport: Viewport, rect: (int32,int32,int32,int32), dest_buffer: Framebuffer, passes: seq[int]) =
|
proc draw_viewport*(self: RenderManager, viewport: Viewport, rect: (int32,int32,int32,int32), dest_buffer: Framebuffer, passes: seq[int]) =
|
||||||
# Configure camera data
|
# Configure camera data
|
||||||
let cam = viewport.debug_camera ?: viewport.camera
|
let cam = if viewport.debug_camera.nonNil:
|
||||||
|
viewport.debug_camera
|
||||||
|
else:
|
||||||
|
viewport.camera
|
||||||
let scene = cam.scene
|
let scene = cam.scene
|
||||||
if self.was_right_eye != viewport.is_right_eye:
|
if self.was_right_eye != viewport.is_right_eye:
|
||||||
self.was_right_eye = viewport.is_right_eye
|
self.was_right_eye = viewport.is_right_eye
|
||||||
|
@ -523,7 +525,7 @@ proc draw_viewport*(self: RenderManager, viewport: Viewport, rect: (int32,int32,
|
||||||
idx = idx shr 1
|
idx = idx shr 1
|
||||||
idx = num_meshes - idx - 1
|
idx = num_meshes - idx - 1
|
||||||
let ob = scene.mesh_passes[1][idx]
|
let ob = scene.mesh_passes[1][idx]
|
||||||
# (ob.last_lod[cam_name].?mesh ? ob).sort_faces(cam_pos)
|
# TODO: LoDs
|
||||||
ob.sort_faces(cam_pos)
|
ob.sort_faces(cam_pos)
|
||||||
for ob in scene.mesh_passes[1]:
|
for ob in scene.mesh_passes[1]:
|
||||||
if ob.visible:
|
if ob.visible:
|
||||||
|
|
|
@ -78,17 +78,18 @@ func toInternalFormat*(format: TextureFormat): GLenum
|
||||||
|
|
||||||
# import sugar
|
# import sugar
|
||||||
|
|
||||||
when not defined(no_pixie):
|
when defined(myouUsePixie):
|
||||||
import pixie
|
import pixie
|
||||||
else:
|
else:
|
||||||
type PixieError = Exception
|
import stb_image/read as stbi
|
||||||
|
const myouConvertHdrToFloat16 {.booldefine.} = true
|
||||||
|
|
||||||
when not defined(nimdoc):
|
when not defined(nimdoc):
|
||||||
import tinyexr
|
import tinyexr
|
||||||
|
|
||||||
import std/bitops
|
import std/bitops
|
||||||
import std/strformat
|
import std/strformat
|
||||||
# import float16
|
import float16
|
||||||
import loadable
|
import loadable
|
||||||
import ddx_ktx
|
import ddx_ktx
|
||||||
|
|
||||||
|
@ -117,10 +118,10 @@ proc stride*(format: TextureFormat): int =
|
||||||
of RG_u8: 2
|
of RG_u8: 2
|
||||||
of RGB_u8: 3
|
of RGB_u8: 3
|
||||||
of RGBA_u8: 4
|
of RGBA_u8: 4
|
||||||
of R_f16: 2
|
of R_u16, R_f16: 2
|
||||||
of RG_f16: 4
|
of RG_u16, RG_f16: 4
|
||||||
of RGB_f16: 6
|
of RGB_u16, RGB_f16: 6
|
||||||
of RGBA_f16: 8
|
of RGBA_u16, RGBA_f16: 8
|
||||||
of R_f32: 4
|
of R_f32: 4
|
||||||
of RG_f32: 8
|
of RG_f32: 8
|
||||||
of RGB_f32: 12
|
of RGB_f32: 12
|
||||||
|
@ -132,9 +133,9 @@ proc stride*(format: TextureFormat): int =
|
||||||
|
|
||||||
proc channel_count*(format: TextureFormat): int =
|
proc channel_count*(format: TextureFormat): int =
|
||||||
case format:
|
case format:
|
||||||
of R_u8, R_f16, R_f32, Depth_u16, Depth_u24, Depth_f32: 1
|
of R_u8, R_u16, R_f16, R_f32, Depth_u16, Depth_u24, Depth_f32: 1
|
||||||
of RG_u8, RG_f16, RG_f32: 2
|
of RG_u8, RG_u16, RG_f16, RG_f32: 2
|
||||||
of SRGB_u8, RGB_u8, RGB_f16, RGB_f32: 3
|
of SRGB_u8, RGB_u8, RGB_u16, RGB_f16, RGB_f32: 3
|
||||||
else: 4
|
else: 4
|
||||||
|
|
||||||
func samplerType*(tex_type: TextureType): string =
|
func samplerType*(tex_type: TextureType): string =
|
||||||
|
@ -155,6 +156,10 @@ func toInternalFormat*(format: TextureFormat): GLenum =
|
||||||
of RG_u8: GL_RG8
|
of RG_u8: GL_RG8
|
||||||
of RGB_u8: GL_RGB8
|
of RGB_u8: GL_RGB8
|
||||||
of RGBA_u8: GL_RGBA8
|
of RGBA_u8: GL_RGBA8
|
||||||
|
of R_u16: GL_R16
|
||||||
|
of RG_u16: GL_RG16
|
||||||
|
of RGB_u16: GL_RGB16
|
||||||
|
of RGBA_u16: GL_RGBA16
|
||||||
of R_f16: GL_R16F
|
of R_f16: GL_R16F
|
||||||
of RG_f16: GL_RG16F
|
of RG_f16: GL_RG16F
|
||||||
of RGB_f16: GL_RGB16F
|
of RGB_f16: GL_RGB16F
|
||||||
|
@ -209,10 +214,10 @@ proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: T
|
||||||
of TexExternal: GL_TEXTURE_EXTERNAL_OES
|
of TexExternal: GL_TEXTURE_EXTERNAL_OES
|
||||||
ts.iformat = format.toInternalFormat
|
ts.iformat = format.toInternalFormat
|
||||||
ts.format = case format:
|
ts.format = case format:
|
||||||
of R_u8, R_f16, R_f32: GL_RED
|
of R_u8, R_u16, R_f16, R_f32: GL_RED
|
||||||
of RG_u8, RG_f16, RG_f32: GL_RG
|
of RG_u8, RG_u16, RG_f16, RG_f32: GL_RG
|
||||||
of SRGB_u8, RGB_u8, RGB_f16, RGB_f32: GL_RGB
|
of SRGB_u8, RGB_u8, RGB_u16, RGB_f16, RGB_f32: GL_RGB
|
||||||
of SRGB_Alpha_u8, RGBA_u8, RGBA_f16, RGBA_f32: GL_RGBA
|
of SRGB_Alpha_u8, RGBA_u8, RGBA_u16, RGBA_f16, RGBA_f32: GL_RGBA
|
||||||
of Depth_u16, Depth_u24, Depth_f32: GL_DEPTH_COMPONENT
|
of Depth_u16, Depth_u24, Depth_f32: GL_DEPTH_COMPONENT
|
||||||
# of Depth_u24_s8: GL_DEPTH_COMPONENT
|
# of Depth_u24_s8: GL_DEPTH_COMPONENT
|
||||||
# else:
|
# else:
|
||||||
|
@ -221,7 +226,7 @@ proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: T
|
||||||
of SRGB_u8, SRGB_Alpha_u8, R_u8, RG_u8, RGB_u8, RGBA_u8: GL_UNSIGNED_BYTE
|
of SRGB_u8, SRGB_Alpha_u8, R_u8, RG_u8, RGB_u8, RGBA_u8: GL_UNSIGNED_BYTE
|
||||||
of R_f16, RG_f16, RGB_f16, RGBA_f16: GL_HALF_FLOAT
|
of R_f16, RG_f16, RGB_f16, RGBA_f16: GL_HALF_FLOAT
|
||||||
of R_f32, RG_f32, RGB_f32, RGBA_f32, Depth_f32: cGL_FLOAT
|
of R_f32, RG_f32, RGB_f32, RGBA_f32, Depth_f32: cGL_FLOAT
|
||||||
of Depth_u16: GL_UNSIGNED_SHORT
|
of R_u16, RG_u16, RGB_u16, RGBA_u16, Depth_u16: GL_UNSIGNED_SHORT
|
||||||
of Depth_u24: GL_UNSIGNED_INT
|
of Depth_u24: GL_UNSIGNED_INT
|
||||||
# of Depth_u24_s8: GL_UNSIGNED_INT
|
# of Depth_u24_s8: GL_UNSIGNED_INT
|
||||||
ts.layer = 0
|
ts.layer = 0
|
||||||
|
@ -404,6 +409,16 @@ proc loadCompressedData*(self: Texture, info: KtxInfo, data: seq[KtxPart]) =
|
||||||
info.internal_format.GLenum, self.width.GLsizei, self.height.GLsizei,
|
info.internal_format.GLenum, self.width.GLsizei, self.height.GLsizei,
|
||||||
0, part.len.GLsizei, part.data)
|
0, part.len.GLsizei, part.data)
|
||||||
|
|
||||||
|
template toOpenArrayByte(p: pointer, a,b: untyped): untyped =
|
||||||
|
cast[ptr UncheckedArray[byte]](p).toOpenArray(a,b)
|
||||||
|
|
||||||
|
template toOpenArray[T](p: pointer, a,b: untyped): untyped =
|
||||||
|
cast[ptr UncheckedArray[T]](p).toOpenArray(a,b)
|
||||||
|
|
||||||
|
proc f32_to_f16(source: ptr UncheckedArray[float32], dest: ptr UncheckedArray[Float16], len: int) =
|
||||||
|
for i in 0 ..< len:
|
||||||
|
dest[i] = source[i].tofloat16(clamp=true)
|
||||||
|
|
||||||
proc loadFileFromPointersLen*(self: Texture, pointers: seq[(pointer, int)], flip = true) =
|
proc loadFileFromPointersLen*(self: Texture, pointers: seq[(pointer, int)], flip = true) =
|
||||||
when not defined(nimdoc):
|
when not defined(nimdoc):
|
||||||
assert self.tex_type != TexCube, "Loading a cube texture from file is not supported yet"
|
assert self.tex_type != TexCube, "Loading a cube texture from file is not supported yet"
|
||||||
|
@ -414,12 +429,17 @@ proc loadFileFromPointersLen*(self: Texture, pointers: seq[(pointer, int)], flip
|
||||||
multilayer_buffer = newArrRef[byte](layer_stride * self.depth)
|
multilayer_buffer = newArrRef[byte](layer_stride * self.depth)
|
||||||
var pos = 0
|
var pos = 0
|
||||||
for (p, len) in pointers:
|
for (p, len) in pointers:
|
||||||
when not defined(no_pixie):
|
when defined(myouUsePixie):
|
||||||
var image: Image
|
var image: Image
|
||||||
|
else:
|
||||||
|
var image: imagePixelData[byte]
|
||||||
|
var image_16: imagePixelData[uint16]
|
||||||
|
var image_f: imagePixelData[float32]
|
||||||
var buffer: ArrRef[byte]
|
var buffer: ArrRef[byte]
|
||||||
# a reference to this pointer is kept with one of the vars above
|
# a reference to this pointer is kept with one of the vars above
|
||||||
var pixels_ptr: pointer
|
var pixels_ptr: pointer
|
||||||
var pixels_len: int
|
var pixels_len: int
|
||||||
|
var flip = flip
|
||||||
if isEXR(p, len):
|
if isEXR(p, len):
|
||||||
let (width, height, pixels) = decodeEXR(p, len)
|
let (width, height, pixels) = decodeEXR(p, len)
|
||||||
assert width == self.width and height == self.height, "Image size mismatch"
|
assert width == self.width and height == self.height, "Image size mismatch"
|
||||||
|
@ -427,11 +447,33 @@ proc loadFileFromPointersLen*(self: Texture, pointers: seq[(pointer, int)], flip
|
||||||
pixels_ptr = buffer[0].addr
|
pixels_ptr = buffer[0].addr
|
||||||
pixels_len = buffer.len
|
pixels_len = buffer.len
|
||||||
else:
|
else:
|
||||||
when not defined(no_pixie):
|
when defined(myouUsePixie):
|
||||||
image = decodeImage(p, len)
|
image = decodeImage(p, len)
|
||||||
assert image.width == self.width and image.height == self.height, "Image size mismatch"
|
assert image.width == self.width and image.height == self.height, "Image size mismatch"
|
||||||
pixels_ptr = image.data[0].addr
|
pixels_ptr = image.data[0].addr
|
||||||
pixels_len = image.data.len * sizeof image.data[0]
|
pixels_len = image.data.len * sizeof image.data[0]
|
||||||
|
else:
|
||||||
|
setFlipVerticallyOnLoad(flip)
|
||||||
|
flip = false
|
||||||
|
var w,h,c = 0
|
||||||
|
if isHDRFromMemory(p.toOpenArrayByte(0, len-1)):
|
||||||
|
image_f = loadFFromMemory(p.toOpenArrayByte(0, len-1), w,h,c,0)
|
||||||
|
pixels_ptr = image_f.data
|
||||||
|
pixels_len = image_f.byteLen
|
||||||
|
when myouConvertHdrToFloat16:
|
||||||
|
f32_to_f16(
|
||||||
|
cast[ptr UncheckedArray[float32]](pixels_ptr),
|
||||||
|
cast[ptr UncheckedArray[Float16]](pixels_ptr),
|
||||||
|
image_f.len)
|
||||||
|
pixels_len = pixels_len div 2
|
||||||
|
elif is16BitFromMemory(p.toOpenArrayByte(0, len-1)):
|
||||||
|
image_16 = load16FromMemory(p.toOpenArrayByte(0, len-1), w,h,c,0)
|
||||||
|
pixels_ptr = image_16.data
|
||||||
|
pixels_len = image_16.byteLen
|
||||||
|
else:
|
||||||
|
image = loadFromMemory(p.toOpenArrayByte(0, len-1), w,h,c,0)
|
||||||
|
pixels_ptr = image.data
|
||||||
|
pixels_len = image.len
|
||||||
assert layer_stride == pixels_len,
|
assert layer_stride == pixels_len,
|
||||||
&"Image '{self.name}' has a length of {pixels_len}, expected {layer_stride}"
|
&"Image '{self.name}' has a length of {pixels_len}, expected {layer_stride}"
|
||||||
if flip:
|
if flip:
|
||||||
|
@ -508,19 +550,25 @@ proc generateMipmap*(self: Texture) =
|
||||||
|
|
||||||
proc getDimensionsFormat(p: pointer, len: int): (int, int, TextureFormat) =
|
proc getDimensionsFormat(p: pointer, len: int): (int, int, TextureFormat) =
|
||||||
when not defined(nimdoc):
|
when not defined(nimdoc):
|
||||||
try:
|
if isEXR(p, len):
|
||||||
when not defined(no_pixie):
|
let dims = getEXRDimensions(p, len)
|
||||||
let dims = decodeImageDimensions(p, len)
|
return (dims[0], dims[1], RGBA_f16)
|
||||||
return (dims.width, dims.height, RGBA_u8)
|
when defined(myouUsePixie):
|
||||||
else: raise PixieError.newException("Pixie not compiled in")
|
let dims = decodeImageDimensions(p, len)
|
||||||
except PixieError as e:
|
return (dims.width, dims.height, RGBA_u8)
|
||||||
# TODO: abstract these functions to e.g. be able to replace these by oiio, etc
|
else:
|
||||||
# and avoid repetitions
|
var width, height, channels = 0
|
||||||
if isEXR(p, len):
|
if not infoFromMemory(p.toOpenArrayByte(0, len-1), width, height, channels):
|
||||||
let dims = getEXRDimensions(p, len)
|
raise ValueError.newException "Could not read image"
|
||||||
return (dims[0], dims[1], RGBA_f16)
|
let hdr = isHDRFromMemory(p.toOpenArrayByte(0, len-1))
|
||||||
else:
|
let is16 = is16BitFromMemory(p.toOpenArrayByte(0, len-1))
|
||||||
raise e
|
# Calculate format with channels, and whether it's hdr or 16 bit
|
||||||
|
assert (RG_u8.int - R_u8.int) == 1 # (just in case someone changes the enum)
|
||||||
|
const toHDR = when myouConvertHdrToFloat16: (R_f16.int-R_u8.int) else: (R_f32.int-R_u8.int)
|
||||||
|
let format = (R_u8.int - 1 + channels +
|
||||||
|
hdr.int * toHDR + is16.int * (R_u16.int-R_u8.int)).TextureFormat
|
||||||
|
dump format
|
||||||
|
return (width, height, format)
|
||||||
|
|
||||||
func to_sRGB*(format: TextureFormat): TextureFormat =
|
func to_sRGB*(format: TextureFormat): TextureFormat =
|
||||||
return case format:
|
return case format:
|
||||||
|
@ -530,15 +578,14 @@ func to_sRGB*(format: TextureFormat): TextureFormat =
|
||||||
|
|
||||||
proc newTexture*(engine: MyouEngine, name: string, p: pointer, len: int, is_sRGB: bool, filter: TextureFilter = Trilinear, depth=1, flip=true): Texture =
|
proc newTexture*(engine: MyouEngine, name: string, p: pointer, len: int, is_sRGB: bool, filter: TextureFilter = Trilinear, depth=1, flip=true): Texture =
|
||||||
# TODO: replace this function by one taking a LoadableResource
|
# TODO: replace this function by one taking a LoadableResource
|
||||||
when not defined(no_pixie):
|
var (width, height, format) = getDimensionsFormat(p, len)
|
||||||
var (width, height, format) = getDimensionsFormat(p, len)
|
if is_sRGB:
|
||||||
if is_sRGB:
|
format = format.to_sRGB
|
||||||
format = format.to_sRGB
|
let self = engine.newTexture(name, width, height, depth, format, filter=filter)
|
||||||
let self = engine.newTexture(name, width, height, depth, format, filter=filter)
|
engine.renderer.enqueue proc() =
|
||||||
engine.renderer.enqueue proc() =
|
self.loadFileFromPointersLen(@[(p, len)], flip=flip)
|
||||||
self.loadFileFromPointersLen(@[(p, len)], flip=flip)
|
self.loaded = true
|
||||||
self.loaded = true
|
return self
|
||||||
return self
|
|
||||||
|
|
||||||
proc newTexture*(engine: MyouEngine, name: string, file_name: string, is_sRGB: bool,
|
proc newTexture*(engine: MyouEngine, name: string, file_name: string, is_sRGB: bool,
|
||||||
filter: TextureFilter = Trilinear,
|
filter: TextureFilter = Trilinear,
|
||||||
|
|
|
@ -1234,17 +1234,17 @@ node_functions = {
|
||||||
let outn = if data_type == 10: # float
|
let outn = if data_type == 10: # float
|
||||||
value = ins["Value"].flt
|
value = ins["Value"].flt
|
||||||
min0 = ins["From Min", 1].flt
|
min0 = ins["From Min", 1].flt
|
||||||
max0 = ins["From Max1", 1].flt
|
max0 = ins["From Max", 1].flt
|
||||||
min1 = ins["To Min", 1].flt
|
min1 = ins["To Min", 1].flt
|
||||||
max1 = ins["To Max1", 1].flt
|
max1 = ins["To Max", 1].flt
|
||||||
steps = ins["Steps", 1].flt
|
steps = ins["Steps", 1].flt
|
||||||
"$0"
|
"$0"
|
||||||
elif data_type == 48: # vec3
|
elif data_type == 48: # vec3
|
||||||
value = ins["Vector"].vec3
|
value = ins["Vector"].vec3
|
||||||
min0 = ins["From Min", 3].vec3
|
min0 = ins["From Min", 3].vec3
|
||||||
max0 = ins["From Max1", 3].vec3
|
max0 = ins["From Max", 3].vec3
|
||||||
min1 = ins["To Min", 3].vec3
|
min1 = ins["To Min", 3].vec3
|
||||||
max1 = ins["To Max1", 3].vec3
|
max1 = ins["To Max", 3].vec3
|
||||||
steps = ins["Steps", 3].vec3
|
steps = ins["Steps", 3].vec3
|
||||||
"$1"
|
"$1"
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -110,8 +110,6 @@ method get_armature*(self: GameObject): Armature {.base.} =
|
||||||
# End forward declarations and ob type methods
|
# End forward declarations and ob type methods
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import elvis
|
|
||||||
|
|
||||||
import std/math
|
import std/math
|
||||||
import std/tables
|
import std/tables
|
||||||
import ../incomplete
|
import ../incomplete
|
||||||
|
@ -120,22 +118,6 @@ import ../graphics/ubo
|
||||||
import ../scene
|
import ../scene
|
||||||
import ./mesh
|
import ./mesh
|
||||||
|
|
||||||
# Alternative to ob type methods using templates instead
|
|
||||||
# TODO: use or delete
|
|
||||||
|
|
||||||
# template is_camera*(self: GameObject): bool = ?self and self.otype == TCamera
|
|
||||||
# template is_light*(self: GameObject): bool = ?self and self.otype == TLight
|
|
||||||
# template is_mesh*(self: GameObject): bool = ?self and self.otype == TMesh
|
|
||||||
# template is_armature*(self: GameObject): bool = ?self and self.otype == TArmature
|
|
||||||
# template get_camera*(self: GameObject): Camera =
|
|
||||||
# if ?self and self.otype == TCamera: cast[Camera](self) else: nil
|
|
||||||
# template get_light*(self: GameObject): Light =
|
|
||||||
# if ?self and self.otype == TLight: cast[Light](self) else: nil
|
|
||||||
# template get_mesh*(self: GameObject): Mesh =
|
|
||||||
# if ?self and self.otype == TMesh: cast[Mesh](self) else: nil
|
|
||||||
# template get_armature*(self: GameObject): Armature =
|
|
||||||
# if ?self and self.otype == TArmature: cast[Armature](self) else: nil
|
|
||||||
|
|
||||||
proc initGameObject*(self: GameObject, engine: MyouEngine, name: string="", scene: Scene=nil): GameObject =
|
proc initGameObject*(self: GameObject, engine: MyouEngine, name: string="", scene: Scene=nil): GameObject =
|
||||||
# Remember to add any new mutable reference to clone()
|
# Remember to add any new mutable reference to clone()
|
||||||
self.engine = engine
|
self.engine = engine
|
||||||
|
@ -585,7 +567,7 @@ iterator children_recursive*(self: GameObject, include_self: static[bool] = fals
|
||||||
# return self.scene?.load_objects(self.get_descendants(true), options)
|
# return self.scene?.load_objects(self.get_descendants(true), options)
|
||||||
|
|
||||||
proc remove*(self: GameObject, recursive: bool = true) =
|
proc remove*(self: GameObject, recursive: bool = true) =
|
||||||
if ?self.scene:
|
if self.scene.nonNil:
|
||||||
self.scene.remove_object(self, recursive)
|
self.scene.remove_object(self, recursive)
|
||||||
|
|
||||||
proc destroy*(self: GameObject, recursive: bool = true) =
|
proc destroy*(self: GameObject, recursive: bool = true) =
|
||||||
|
|
|
@ -52,8 +52,6 @@ proc ensure_capacity*(self: Mesh, extra_elements: int)
|
||||||
proc write_vaos*(self: MeshData)
|
proc write_vaos*(self: MeshData)
|
||||||
# End forward declarations and ob type methods
|
# End forward declarations and ob type methods
|
||||||
|
|
||||||
import elvis
|
|
||||||
import ../quat
|
|
||||||
|
|
||||||
import std/algorithm
|
import std/algorithm
|
||||||
# import std/sequtils
|
# import std/sequtils
|
||||||
|
@ -65,6 +63,7 @@ import ./gameobject
|
||||||
import ../scene
|
import ../scene
|
||||||
import ../util
|
import ../util
|
||||||
import ../attributes
|
import ../attributes
|
||||||
|
import ../quat
|
||||||
|
|
||||||
export arr_ref
|
export arr_ref
|
||||||
export tables
|
export tables
|
||||||
|
@ -167,7 +166,7 @@ proc gpu_buffers_upload*(self: MeshData) =
|
||||||
if not had_indices:
|
if not had_indices:
|
||||||
self.num_indices.add(num_indices.int32)
|
self.num_indices.add(num_indices.int32)
|
||||||
elif not had_indices:
|
elif not had_indices:
|
||||||
self.num_indices.add((buffer_size div (self.stride ?: 0)).int32)
|
self.num_indices.add((buffer_size div self.stride).int32)
|
||||||
self.index_buffers.add(ib)
|
self.index_buffers.add(ib)
|
||||||
if self.use_tf:
|
if self.use_tf:
|
||||||
self.tf_vbos.setLen 2
|
self.tf_vbos.setLen 2
|
||||||
|
@ -405,10 +404,7 @@ proc load_from_va_ia*(self: Mesh,
|
||||||
|
|
||||||
if self.data != nil:
|
if self.data != nil:
|
||||||
self.data.remove(self)
|
self.data.remove(self)
|
||||||
# if @hash and (@data = @engine.mesh_datas[@hash])?
|
# TODO: hash meshes to reuse existing copies automatically
|
||||||
# @data.users.push @
|
|
||||||
# @engine.main_loop?.reset_timeout()
|
|
||||||
# return
|
|
||||||
var data = newMeshData(self.engine)
|
var data = newMeshData(self.engine)
|
||||||
when defined(myouUseRenderdoc):
|
when defined(myouUseRenderdoc):
|
||||||
data.name = self.name
|
data.name = self.name
|
||||||
|
@ -460,14 +456,14 @@ proc load_from_va_ia*(self: Mesh,
|
||||||
|
|
||||||
proc add_modifier*(self: Mesh, modifier: VertexModifier) =
|
proc add_modifier*(self: Mesh, modifier: VertexModifier) =
|
||||||
self.vertex_modifiers.add(modifier)
|
self.vertex_modifiers.add(modifier)
|
||||||
if ?modifier.prepare_mesh and ?self.data:
|
if modifier.prepare_mesh.nonNil and self.data.nonNil:
|
||||||
echo &"applying modifiers of {self.name} after it was already loaded"
|
echo &"applying modifiers of {self.name} after it was already loaded"
|
||||||
modifier.prepare_mesh(self)
|
modifier.prepare_mesh(self)
|
||||||
# self.update_signature()
|
# self.update_signature()
|
||||||
|
|
||||||
proc insert_modifier*(self: Mesh, index: int, modifier: VertexModifier) =
|
proc insert_modifier*(self: Mesh, index: int, modifier: VertexModifier) =
|
||||||
self.vertex_modifiers.insert(modifier, index)
|
self.vertex_modifiers.insert(modifier, index)
|
||||||
if ?modifier.prepare_mesh and ?self.data:
|
if modifier.prepare_mesh.nonNil and self.data.nonNil:
|
||||||
echo &"applying modifiers of {self.name} after it was already loaded"
|
echo &"applying modifiers of {self.name} after it was already loaded"
|
||||||
modifier.prepare_mesh(self)
|
modifier.prepare_mesh(self)
|
||||||
# self.update_signature()
|
# self.update_signature()
|
||||||
|
@ -561,7 +557,7 @@ proc remove_modifier*(self: Mesh, modifier: VertexModifier) =
|
||||||
|
|
||||||
proc clone_impl*(self: Mesh, clone: Mesh): Mesh =
|
proc clone_impl*(self: Mesh, clone: Mesh): Mesh =
|
||||||
clone.last_lod.clear()
|
clone.last_lod.clear()
|
||||||
if ?clone.data:
|
if clone.data.nonNil:
|
||||||
clone.data.users.add(clone)
|
clone.data.users.add(clone)
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
import ../types
|
import ../types
|
||||||
import vmath except Quat
|
import vmath except Quat
|
||||||
|
|
||||||
import staticglfw as glfw
|
import nglfw as glfw
|
||||||
type Window* = glfw.Window
|
type Window* = glfw.Window
|
||||||
|
|
||||||
# proc make_window*(width, height: int32, title: string): Window
|
# proc make_window*(width, height: int32, title: string): Window
|
||||||
|
@ -154,7 +154,7 @@ proc init_graphics*(engine: MyouEngine, width, height: int32, title: string,
|
||||||
# TODO!! Option to delay this to simulate the situation in mobile platforms
|
# TODO!! Option to delay this to simulate the situation in mobile platforms
|
||||||
|
|
||||||
# Init GLFW
|
# Init GLFW
|
||||||
if glfw.init() == 0:
|
if not glfw.init():
|
||||||
raise newException(Exception, "Failed to Initialize GLFW")
|
raise newException(Exception, "Failed to Initialize GLFW")
|
||||||
|
|
||||||
let major = opengl_version div 100
|
let major = opengl_version div 100
|
||||||
|
@ -209,12 +209,12 @@ var current_screen: Screen
|
||||||
|
|
||||||
proc platform_switch_screen*(screen: Screen): bool {.inline.} =
|
proc platform_switch_screen*(screen: Screen): bool {.inline.} =
|
||||||
if current_screen != screen:
|
if current_screen != screen:
|
||||||
screen.window.makeContextCurrent()
|
cast[Window](screen.window).makeContextCurrent()
|
||||||
current_screen = screen
|
current_screen = screen
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# proc platform_swap_buffers*(screen: Screen) {.inline.} =
|
# proc platform_swap_buffers*(screen: Screen) {.inline.} =
|
||||||
# screen.window.swapBuffers()
|
# cast[Window](screen.window).swapBuffers()
|
||||||
|
|
||||||
proc start_platform_main_loop*(engine: MyouEngine, main_loop: proc(self: MyouEngine)) =
|
proc start_platform_main_loop*(engine: MyouEngine, main_loop: proc(self: MyouEngine)) =
|
||||||
while windows.len != 0:
|
while windows.len != 0:
|
||||||
|
@ -231,4 +231,4 @@ proc start_platform_main_loop*(engine: MyouEngine, main_loop: proc(self: MyouEng
|
||||||
glfw.terminate()
|
glfw.terminate()
|
||||||
|
|
||||||
proc myouAndroidGetActivity*(): pointer =
|
proc myouAndroidGetActivity*(): pointer =
|
||||||
assert false, "Not using Android"
|
assert false, "Not using Android"
|
||||||
|
|
|
@ -64,7 +64,6 @@ proc render_all_cubemaps*(self: Scene, use_roughness_prefiltering: bool, mipmap_
|
||||||
|
|
||||||
import vmath except Quat
|
import vmath except Quat
|
||||||
import ./quat
|
import ./quat
|
||||||
import elvis
|
|
||||||
import std/algorithm
|
import std/algorithm
|
||||||
import std/math
|
import std/math
|
||||||
import std/options
|
import std/options
|
||||||
|
@ -163,13 +162,13 @@ proc add_object*(self: Scene, ob: GameObject,
|
||||||
ob.parent = p
|
ob.parent = p
|
||||||
p.children.add(ob)
|
p.children.add(ob)
|
||||||
var armature = p.get_armature
|
var armature = p.get_armature
|
||||||
if ?armature and ?parent_bone:
|
if armature.nonNil and parent_bone != "":
|
||||||
var bone = armature.bones[parent_bone]
|
var bone = armature.bones[parent_bone]
|
||||||
if ?bone:
|
if bone.nonNil:
|
||||||
ob.parent_bone_index = armature.bone_list.find(bone)
|
ob.parent_bone_index = armature.bone_list.find(bone)
|
||||||
bone.object_children.add(ob)
|
bone.object_children.add(ob)
|
||||||
var mesh = ob.get_mesh
|
var mesh = ob.get_mesh
|
||||||
if ?mesh:
|
if mesh.nonNil:
|
||||||
# TODO: not having number of passes hardcoded
|
# TODO: not having number of passes hardcoded
|
||||||
for p in 0'i32 .. 2:
|
for p in 0'i32 .. 2:
|
||||||
if p in mesh.passes:
|
if p in mesh.passes:
|
||||||
|
@ -196,12 +195,12 @@ proc remove_object*(self: Scene, ob: GameObject, recursive: bool = true) =
|
||||||
self.objects.del(ob.name)
|
self.objects.del(ob.name)
|
||||||
self.parents.del(ob.original_name)
|
self.parents.del(ob.original_name)
|
||||||
var mesh = ob.get_mesh
|
var mesh = ob.get_mesh
|
||||||
if ?mesh:
|
if mesh.nonNil:
|
||||||
self.mesh_passes[0].remove mesh
|
self.mesh_passes[0].remove mesh
|
||||||
self.mesh_passes[1].remove mesh
|
self.mesh_passes[1].remove mesh
|
||||||
self.fg_pass.remove mesh
|
self.fg_pass.remove mesh
|
||||||
self.bg_pass.remove mesh
|
self.bg_pass.remove mesh
|
||||||
if ?mesh.data:
|
if mesh.data.nonNil:
|
||||||
mesh.data.remove(mesh)
|
mesh.data.remove(mesh)
|
||||||
elif ob.is_camera:
|
elif ob.is_camera:
|
||||||
for screen in self.engine.screens:
|
for screen in self.engine.screens:
|
||||||
|
@ -217,9 +216,9 @@ proc remove_object*(self: Scene, ob: GameObject, recursive: bool = true) =
|
||||||
self.lights.remove light
|
self.lights.remove light
|
||||||
elif ob.is_armature:
|
elif ob.is_armature:
|
||||||
self.armatures.remove ob.get_armature
|
self.armatures.remove ob.get_armature
|
||||||
if ob.parent_bone_index != -1 and ?ob.parent:
|
if ob.parent_bone_index != -1 and ob.parent.nonNil:
|
||||||
var ar = ob.parent.get_armature
|
var ar = ob.parent.get_armature
|
||||||
if ?ar and ar.bone_list.len > ob.parent_bone_index:
|
if ar.nonNil and ar.bone_list.len > ob.parent_bone_index:
|
||||||
ar.bone_list[ob.parent_bone_index].object_children.remove ob
|
ar.bone_list[ob.parent_bone_index].object_children.remove ob
|
||||||
ob.body.destroy()
|
ob.body.destroy()
|
||||||
# TODO: Remove probes if they have no users
|
# TODO: Remove probes if they have no users
|
||||||
|
@ -235,7 +234,7 @@ proc remove_object*(self: Scene, ob: GameObject, recursive: bool = true) =
|
||||||
proc make_parent*(self: Scene, parent: GameObject, child: GameObject,
|
proc make_parent*(self: Scene, parent: GameObject, child: GameObject,
|
||||||
keep_transform: bool = true) =
|
keep_transform: bool = true) =
|
||||||
assert parent != nil and child != nil, "Arguments 'parent' and 'child' can't be nil."
|
assert parent != nil and child != nil, "Arguments 'parent' and 'child' can't be nil."
|
||||||
if ?child.parent:
|
if child.parent.nonNil:
|
||||||
self.clear_parent(child, keep_transform)
|
self.clear_parent(child, keep_transform)
|
||||||
# TODO: should we store the index in the objects
|
# TODO: should we store the index in the objects
|
||||||
# to make this check faster?
|
# to make this check faster?
|
||||||
|
@ -313,7 +312,7 @@ proc reorder_children*(self: Scene) =
|
||||||
reorder(c)
|
reorder(c)
|
||||||
|
|
||||||
for ob in self.children:
|
for ob in self.children:
|
||||||
if ?ob.parent:
|
if ob.parent.nonNil:
|
||||||
continue
|
continue
|
||||||
reorder(ob)
|
reorder(ob)
|
||||||
self.children_are_ordered = true
|
self.children_are_ordered = true
|
||||||
|
@ -382,9 +381,10 @@ proc new_mesh*(self: Scene, name: string,
|
||||||
proc set_active_camera*(self: Scene, camera: Camera) =
|
proc set_active_camera*(self: Scene, camera: Camera) =
|
||||||
self.active_camera = camera
|
self.active_camera = camera
|
||||||
if camera.scene != self:
|
if camera.scene != self:
|
||||||
self.add_object(camera, camera.name ?: "Camera")
|
let name = if camera.name != "": camera.name else: "Camera"
|
||||||
|
self.add_object(camera, name)
|
||||||
if self.add_viewport_automatically:
|
if self.add_viewport_automatically:
|
||||||
if not ?self.engine.screens[0].viewports:
|
if self.engine.screens[0].viewports.len == 0:
|
||||||
self.engine.screens[0].add_viewport(camera)
|
self.engine.screens[0].add_viewport(camera)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,7 @@ type
|
||||||
TArmature
|
TArmature
|
||||||
|
|
||||||
GameObject* = ref object of RootObj
|
GameObject* = ref object of RootObj
|
||||||
|
# TODO: remove otype
|
||||||
otype*: ObjectType ## private
|
otype*: ObjectType ## private
|
||||||
engine*: MyouEngine ## private
|
engine*: MyouEngine ## private
|
||||||
debug*: bool ## private
|
debug*: bool ## private
|
||||||
|
@ -590,7 +591,6 @@ type
|
||||||
|
|
||||||
TextureFormat* = enum
|
TextureFormat* = enum
|
||||||
# TODO: signed normalized formats
|
# TODO: signed normalized formats
|
||||||
# TODO: Float16
|
|
||||||
# TODO: uncommon formats
|
# TODO: uncommon formats
|
||||||
SRGB_u8
|
SRGB_u8
|
||||||
SRGB_Alpha_u8
|
SRGB_Alpha_u8
|
||||||
|
@ -598,6 +598,10 @@ type
|
||||||
RG_u8
|
RG_u8
|
||||||
RGB_u8
|
RGB_u8
|
||||||
RGBA_u8
|
RGBA_u8
|
||||||
|
R_u16
|
||||||
|
RG_u16
|
||||||
|
RGB_u16
|
||||||
|
RGBA_u16
|
||||||
R_f16
|
R_f16
|
||||||
RG_f16
|
RG_f16
|
||||||
RGB_f16
|
RGB_f16
|
||||||
|
|
|
@ -96,9 +96,10 @@ func align*[T: SomeInteger](n, align: T): T =
|
||||||
|
|
||||||
func bytelen*[T](s: seq[T]): int = s.len * sizeof(T)
|
func bytelen*[T](s: seq[T]): int = s.len * sizeof(T)
|
||||||
|
|
||||||
func get_or_default*[T](s: seq[T], i: int): T =
|
func get_or_default*[T](s: seq[T], i: int, default: T = T.default): T =
|
||||||
if i >= s.low and i <= s.high:
|
if i >= s.low and i <= s.high:
|
||||||
return s[i]
|
return s[i]
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
when defined(js):
|
when defined(js):
|
||||||
|
@ -229,3 +230,5 @@ template staticOrDebugRead*(path: string): string =
|
||||||
readFile dir & path
|
readFile dir & path
|
||||||
else:
|
else:
|
||||||
staticRead path
|
staticRead path
|
||||||
|
|
||||||
|
template nonNil*(x: untyped): bool = x != nil
|
||||||
|
|
Loading…
Reference in a new issue