Add tests: triangle, lines, texture, vertex_modifier, armature, msaa1, msaa2.
This commit is contained in:
parent
bde930692d
commit
a4007a36b0
8 changed files with 432 additions and 0 deletions
109
tests/armature.nim
Normal file
109
tests/armature.nim
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
import std/sequtils
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera()
|
||||||
|
|
||||||
|
# Move the camera upwards (the default rotation looks down)
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
let armature = engine.newArmature(scene=scene)
|
||||||
|
let b0 = armature.add_bone("Bone", vec3(), quat(), 0, "", 0.5)
|
||||||
|
let b1 = armature.add_bone("Bone1", vec3(0,0.5,0), quat(), 1, "Bone", 0.5)
|
||||||
|
let b2 = armature.add_bone("Bone2", vec3(0,0.5,0), quat(), 2, "Bone1", 0.5)
|
||||||
|
let b3 = armature.add_bone("Bone3", vec3(0,0.5,0), quat(), 3, "Bone2", 0.5)
|
||||||
|
armature.update_rest_matrices
|
||||||
|
armature.position.y = -1
|
||||||
|
|
||||||
|
var layout: AttributeList
|
||||||
|
layout.add Attribute(name: "vertex", dtype: Float, count: 3)
|
||||||
|
layout.add Attribute(name: "weights", dtype: UByte, count: 4)
|
||||||
|
layout.add Attribute(name: "b_indices", dtype: UByte, count: 4)
|
||||||
|
var vertices: seq[(Vec3, array[4, uint8], array[4, uint8])]
|
||||||
|
var indices: seq[uint16]
|
||||||
|
const faces_x = 2
|
||||||
|
const faces_y = 16
|
||||||
|
for y in 0 .. faces_y:
|
||||||
|
for x in 0 .. faces_x:
|
||||||
|
let pos = vec3(0.5 * (x/faces_x - 0.5), 2f * (y/faces_y), -0.1)
|
||||||
|
let p = vec3(0, pos.y, 0)
|
||||||
|
var weights = [
|
||||||
|
clamp(0.5-(b0.dist_to_sphere(p) * 3), 0, 1),
|
||||||
|
clamp(0.5-(b1.dist_to_sphere(p) * 3), 0, 1),
|
||||||
|
clamp(0.5-(b2.dist_to_sphere(p) * 3), 0, 1),
|
||||||
|
clamp(0.5-(b3.dist_to_sphere(p) * 3), 0, 1),
|
||||||
|
]
|
||||||
|
let sum = weights.foldl a+b
|
||||||
|
let w_u8 = weights.mapIt uint8(255 * it/sum)
|
||||||
|
let w_u8a = [w_u8[0], w_u8[1], w_u8[2], w_u8[3]]
|
||||||
|
vertices.add (pos, w_u8a, [0'u8,1,2,3])
|
||||||
|
for y in 0'u16 ..< faces_y.uint16:
|
||||||
|
let p = y * (faces_x.uint16 + 1)
|
||||||
|
for x in p ..< p + faces_x.uint16:
|
||||||
|
let x2 = x + faces_x.uint16 + 1
|
||||||
|
indices.add @[
|
||||||
|
x, x+1, x2,
|
||||||
|
x2, x+1, x2+1,
|
||||||
|
]
|
||||||
|
|
||||||
|
let grid = scene.newMesh("grid",
|
||||||
|
layout = layout,
|
||||||
|
vertex_array = vertices,
|
||||||
|
index_array = indices,
|
||||||
|
)
|
||||||
|
grid.parent_to armature, keep_transform=false
|
||||||
|
grid.armature = armature
|
||||||
|
grid.add_modifier engine.newArmatureModifier(4)
|
||||||
|
grid.materials.add engine.newSolidMaterial("blue", vec4(0.1,0.3,1,1))
|
||||||
|
|
||||||
|
# TODO: Move visualization of armature wireframe to the engine
|
||||||
|
|
||||||
|
let wireframe = scene.newMesh("wireframe", draw_method=Lines, vertex_count=8)
|
||||||
|
wireframe.parent_to armature, keep_transform=false
|
||||||
|
wireframe.materials.add engine.newSolidMaterial("white", vec4(1))
|
||||||
|
|
||||||
|
const OCTAEDRON = @[
|
||||||
|
vec3(0), vec3(-0.1, 0.1, -0.1),
|
||||||
|
vec3(0), vec3(-0.1, 0.1, 0.1),
|
||||||
|
vec3(0), vec3(0.1, 0.1, -0.1),
|
||||||
|
vec3(0), vec3(0.1, 0.1, 0.1),
|
||||||
|
vec3(0.1, 0.1, 0.1), vec3(-0.1, 0.1, -0.1),
|
||||||
|
vec3(-0.1, 0.1, -0.1), vec3(-0.1, 0.1, 0.1),
|
||||||
|
vec3(-0.1, 0.1, 0.1), vec3(0.1, 0.1, -0.1),
|
||||||
|
vec3(0.1, 0.1, -0.1), vec3(0.1, 0.1, 0.1),
|
||||||
|
vec3(-0.1, 0.1, -0.1), vec3(0,1,0),
|
||||||
|
vec3(-0.1, 0.1, 0.1), vec3(0,1,0),
|
||||||
|
vec3(0.1, 0.1, -0.1), vec3(0,1,0),
|
||||||
|
vec3(0.1, 0.1, 0.1), vec3(0,1,0),
|
||||||
|
]
|
||||||
|
|
||||||
|
proc update_wireframe() =
|
||||||
|
armature.recalculate_bone_matrices() # only needed here for visualization
|
||||||
|
wireframe.clear_vertices()
|
||||||
|
wireframe.ensure_capacity(OCTAEDRON.len * armature.bone_list.len)
|
||||||
|
for bone in armature.bone_list:
|
||||||
|
let m = bone.matrix
|
||||||
|
for point in OCTAEDRON:
|
||||||
|
wireframe.add_vertex(m * (bone.blength * point))
|
||||||
|
wireframe.data.update_varray()
|
||||||
|
|
||||||
|
update_wireframe()
|
||||||
|
|
||||||
|
var time = -1.0
|
||||||
|
scene.pre_draw_callbacks.add proc(scene: Scene, dt: float) =
|
||||||
|
time += dt
|
||||||
|
if time < 0:
|
||||||
|
return
|
||||||
|
let f = time * 2f
|
||||||
|
const w = 1.0
|
||||||
|
armature.bones["Bone"].rotation = quat().rotateZ(-sin(f) * w)
|
||||||
|
armature.bones["Bone1"].rotation = quat().rotateZ(-sin(f*1.1) * w)
|
||||||
|
armature.bones["Bone2"].rotation = quat().rotateZ(-sin(f*1.2) * w)
|
||||||
|
armature.bones["Bone3"].rotation = quat().rotateZ(-sin(f*1.4) * w)
|
||||||
|
update_wireframe()
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
27
tests/lines.nim
Normal file
27
tests/lines.nim
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
import random
|
||||||
|
|
||||||
|
# NOT calling this to have always the same results
|
||||||
|
#randomize()
|
||||||
|
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera(cam_type = Orthographic, ortho_scale = 2)
|
||||||
|
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# vertex_count is the initial capacity and is not necessary
|
||||||
|
let lines = scene.newMesh("lines", draw_method=Lines, vertex_count=64)
|
||||||
|
lines.materials.add engine.newSolidMaterial("white", vec4(1))
|
||||||
|
|
||||||
|
scene.pre_draw_callbacks.add proc(scene: Scene, dt: float) =
|
||||||
|
# ensure_capacity enlarges the size of the mesh if the next N vertices
|
||||||
|
# don't fit, by making it at least twice the size
|
||||||
|
lines.ensure_capacity(1)
|
||||||
|
lines.add_vertex(vec3(rand(1f), rand(1f), 0) * 2f - 1f)
|
||||||
|
# call update_varray() only once after making changes
|
||||||
|
lines.data.update_varray()
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
25
tests/msaa1.nim
Normal file
25
tests/msaa1.nim
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
import random
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768, context_msaa_samples=4)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera(cam_type = Orthographic, ortho_scale = 2)
|
||||||
|
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# vertex_count is the initial capacity and is not necessary
|
||||||
|
let lines = scene.newMesh("lines", draw_method=Lines, vertex_count=64)
|
||||||
|
lines.materials.add engine.newSolidMaterial("white", vec4(1))
|
||||||
|
|
||||||
|
scene.pre_draw_callbacks.add proc(scene: Scene, dt: float) =
|
||||||
|
# ensure_capacity enlarges the size of the mesh if the next N vertices
|
||||||
|
# don't fit, by making it at least twice the size
|
||||||
|
lines.ensure_capacity(1)
|
||||||
|
lines.add_vertex(vec3(rand(1f), rand(1f), 0) * 2f - 1f)
|
||||||
|
# call update_varray() only once after making changes
|
||||||
|
lines.data.update_varray()
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
30
tests/msaa2.nim
Normal file
30
tests/msaa2.nim
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
import random
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera(cam_type = Orthographic, ortho_scale = 2)
|
||||||
|
|
||||||
|
# This method allows changing the amount of antialiasing samples at any point,
|
||||||
|
# and it will resize, add or remove the multisampled framebuffer
|
||||||
|
engine.screen.set_MSAA_samples 4
|
||||||
|
|
||||||
|
# Move the camera upwards (the default rotation looks down)
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# vertex_count is the initial capacity and is not necessary
|
||||||
|
let lines = scene.newMesh("lines", draw_method=Lines, vertex_count=64)
|
||||||
|
lines.materials.add engine.newSolidMaterial("white", vec4(1))
|
||||||
|
|
||||||
|
scene.pre_draw_callbacks.add proc(scene: Scene, dt: float) =
|
||||||
|
# ensure_capacity enlarges the size of the mesh if the next N vertices
|
||||||
|
# don't fit, by making it at least twice the size
|
||||||
|
lines.ensure_capacity(1)
|
||||||
|
lines.add_vertex(vec3(rand(1f), rand(1f), 0) * 2f - 1f)
|
||||||
|
# call update_varray() only once after making changes
|
||||||
|
lines.data.update_varray()
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
2
tests/nim.cfg
Normal file
2
tests/nim.cfg
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
path:"../libs/packages/"
|
||||||
|
debugger: native
|
74
tests/texture.nim
Normal file
74
tests/texture.nim
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera() # this sets the active camera if there's none
|
||||||
|
scene.background_color = vec4(0.1, 0.1, 0.1, 1)
|
||||||
|
|
||||||
|
# Move the camera upwards (the default rotation looks down)
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# Create a simple square mesh with UV
|
||||||
|
let quad = scene.newMesh("quad",
|
||||||
|
common_attributes = {vertex, uv},
|
||||||
|
vertex_array = @[
|
||||||
|
# x, y, z, U, V,
|
||||||
|
-1f, -1, 0, 0, 0,
|
||||||
|
1, -1, 0, 1, 0,
|
||||||
|
-1, 1, 0, 0, 1,
|
||||||
|
1, 1, 0, 1, 1,
|
||||||
|
],
|
||||||
|
index_array = @[0'u16, 1, 2, 2, 1, 3],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make the object wider with a 3:2 aspect ratio
|
||||||
|
quad.scale.x = 1.5
|
||||||
|
|
||||||
|
# This example texture is 1 pixel wide and 8 pixels high,
|
||||||
|
# to make a stripped flag
|
||||||
|
# NOTE: The colors are SRGB_u8, not RGB, but we're skipping output encoding
|
||||||
|
# in the shader for simplicity
|
||||||
|
let width = 1
|
||||||
|
let height = 8
|
||||||
|
let format = RGB_u8
|
||||||
|
|
||||||
|
# The texture goes from bottom to top
|
||||||
|
# (unless we invert the Y coordinate of the UV)
|
||||||
|
let pixels = @[
|
||||||
|
115, 41, 130,
|
||||||
|
36, 64, 142,
|
||||||
|
0, 128, 38,
|
||||||
|
255, 237, 0,
|
||||||
|
255, 140, 0,
|
||||||
|
228, 3, 3,
|
||||||
|
120, 79, 23,
|
||||||
|
0, 0, 0,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Create the texture, use Nearest filter
|
||||||
|
# to have a sharp bands instead of a gradient
|
||||||
|
doAssert width * height * 3 == pixels.len
|
||||||
|
let texture = engine.newTexture("test",
|
||||||
|
width = width, height = height,
|
||||||
|
format = format, filter = Nearest,
|
||||||
|
pixels = newArrRef[uint8](pixels).to float32)
|
||||||
|
|
||||||
|
# Minimal example of a material with a UV and a texture uniform
|
||||||
|
quad.materials.add engine.newMaterial("shadeless texture",
|
||||||
|
fragment = """
|
||||||
|
uniform sampler2D tex;
|
||||||
|
in vec2 uv;
|
||||||
|
out vec4 glOutColor;
|
||||||
|
void main(){
|
||||||
|
glOutColor = texture(tex, uv);
|
||||||
|
}""",
|
||||||
|
varyings = @[Varying(vtype: Uv, varname: "uv")],
|
||||||
|
textures = {
|
||||||
|
"tex": texture,
|
||||||
|
}.toOrderedTable,
|
||||||
|
)
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
28
tests/triangle.nim
Normal file
28
tests/triangle.nim
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera() # this sets the active camera if there's none
|
||||||
|
|
||||||
|
# Move the camera upwards (the default rotation looks down)
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# The default layout is vertex position (vec3) and color (uint8 RGBA).
|
||||||
|
# This seq can be of any type as long as it matches the underlying mesh layout.
|
||||||
|
let vertices = @[
|
||||||
|
(vec3(-1.2, -1, 0), [255'u8, 255, 0, 255]),
|
||||||
|
(vec3( 1.2, -1, 0), [0'u8, 255, 255, 255]),
|
||||||
|
(vec3( 0, 1, 0), [255'u8, 0, 255, 255]),
|
||||||
|
]
|
||||||
|
let triangle = scene.newMesh("triangle", vertex_array=vertices)
|
||||||
|
|
||||||
|
# A predefined material that just draws the vertex colors
|
||||||
|
triangle.materials.add engine.newVertexColorMaterial()
|
||||||
|
|
||||||
|
# A new scene is disabled by default, we need to enable it
|
||||||
|
scene.enable_render()
|
||||||
|
|
||||||
|
# This should be the last line of code of the main module
|
||||||
|
engine.run()
|
137
tests/vertex_modifier.nim
Normal file
137
tests/vertex_modifier.nim
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
|
||||||
|
import myou_engine
|
||||||
|
|
||||||
|
# A vertex modifier allows us to inject vertex shader code
|
||||||
|
# while using the autogenerated vertex shader
|
||||||
|
|
||||||
|
proc newWaveModifier*(engine: MyouEngine): VertexModifier =
|
||||||
|
|
||||||
|
# get_code is called when a shader is created for the mesh
|
||||||
|
result.get_code = proc(v: seq[Varying]): VertexModifierCodeLines =
|
||||||
|
# uniform_lines go in the global scope, for uniforms
|
||||||
|
# and global functions
|
||||||
|
result.uniform_lines = @[
|
||||||
|
"layout(std140) uniform WaveModifier {",
|
||||||
|
" float wave_time;",
|
||||||
|
"};",
|
||||||
|
"vec3 waveFlag(vec3 pos, float time) {",
|
||||||
|
" float waveIntensity = (pos.x + 1.0) / 2.0;",
|
||||||
|
" float wave = sin(pos.x * 4.0 - time * 5.0 + pos.y * 3.0) * 0.5;",
|
||||||
|
" wave += sin(pos.x * 6.0 + time * 3.5) * 0.3;",
|
||||||
|
" pos.z += wave * waveIntensity * 0.9;",
|
||||||
|
" pos.y -= waveIntensity * waveIntensity * 0.3;",
|
||||||
|
" ",
|
||||||
|
" return pos;",
|
||||||
|
"}",
|
||||||
|
]
|
||||||
|
# body lines are inserted after reading the local vertex position
|
||||||
|
# and normal, called co (vec4) and normal (vec3) respectively
|
||||||
|
result.body_lines = @[
|
||||||
|
"co.xyz = waveFlag(co.xyz, wave_time);",
|
||||||
|
]
|
||||||
|
|
||||||
|
# Size is 4 because of std140 requirements
|
||||||
|
let ubo = engine.renderer.newUBO("WaveModifier", float32, 4)
|
||||||
|
result.ubo = ubo
|
||||||
|
|
||||||
|
result.update = proc(m: Mesh) =
|
||||||
|
var data = ubo.storage(float32)
|
||||||
|
data[0] = m.scene.time
|
||||||
|
ubo.update()
|
||||||
|
|
||||||
|
|
||||||
|
# Create engine, scene, camera
|
||||||
|
let engine = newMyouEngine(1024, 768)
|
||||||
|
let scene = engine.newScene()
|
||||||
|
let cam = scene.newCamera() # this sets the active camera if there's none
|
||||||
|
scene.background_color = vec4(0.1, 0.1, 0.1, 1)
|
||||||
|
|
||||||
|
# Move the camera upwards (the default rotation looks down)
|
||||||
|
cam.position.z = 10
|
||||||
|
|
||||||
|
# Create a grid mesh with UV
|
||||||
|
# The dimensions are the amount of faces,
|
||||||
|
# or the amount of vertices minus one
|
||||||
|
const grid_x = 64
|
||||||
|
const grid_y = 48
|
||||||
|
var vertices: seq[float32]
|
||||||
|
for y in 0 ..< grid_y + 1:
|
||||||
|
for x in 0 ..< grid_x + 1:
|
||||||
|
vertices.add @[
|
||||||
|
-1f + x.float32 * (2f / grid_x),
|
||||||
|
-1f + y.float32 * (2f / grid_y),
|
||||||
|
0,
|
||||||
|
x / grid_x, y / grid_y,
|
||||||
|
]
|
||||||
|
var indices: seq[uint16]
|
||||||
|
for y in 0'u16 ..< grid_y:
|
||||||
|
let p = y * (grid_x + 1)
|
||||||
|
for x in p ..< p + grid_x:
|
||||||
|
let x2 = x + grid_x + 1
|
||||||
|
indices.add @[
|
||||||
|
x, x+1, x2,
|
||||||
|
x2, x+1, x2+1,
|
||||||
|
]
|
||||||
|
|
||||||
|
let grid = scene.newMesh("grid",
|
||||||
|
common_attributes = {vertex, uv},
|
||||||
|
vertex_array = vertices,
|
||||||
|
index_array = indices,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make the object wider with a 3:2 aspect ratio
|
||||||
|
grid.scale.x = 1.5
|
||||||
|
|
||||||
|
# Add the vertex modifier
|
||||||
|
grid.get_mesh.add_modifier newWaveModifier(engine)
|
||||||
|
|
||||||
|
# This example texture is 1 pixel wide and 8 pixels high,
|
||||||
|
# to make a stripped flag
|
||||||
|
# NOTE: The colors are SRGB_u8, not RGB, but we're skipping output encoding
|
||||||
|
# in the shader for simplicity
|
||||||
|
let width = 1
|
||||||
|
let height = 8
|
||||||
|
let format = RGB_u8
|
||||||
|
|
||||||
|
# The texture goes from bottom to top
|
||||||
|
# (unless we invert the Y coordinate of the UV)
|
||||||
|
let pixels = @[
|
||||||
|
115, 41, 130,
|
||||||
|
36, 64, 142,
|
||||||
|
0, 128, 38,
|
||||||
|
255, 237, 0,
|
||||||
|
255, 140, 0,
|
||||||
|
228, 3, 3,
|
||||||
|
120, 79, 23,
|
||||||
|
0, 0, 0,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Create the texture, use Nearest filter
|
||||||
|
# to have a sharp bands instead of a gradient
|
||||||
|
doAssert width * height * 3 == pixels.len
|
||||||
|
let texture = engine.newTexture("test",
|
||||||
|
width = width, height = height,
|
||||||
|
format = format, filter = Nearest,
|
||||||
|
pixels = newArrRef[uint8](pixels).to float32)
|
||||||
|
|
||||||
|
# Minimal example of a material with a UV and a texture uniform
|
||||||
|
grid.materials.add engine.newMaterial("shadeless texture",
|
||||||
|
fragment = """
|
||||||
|
uniform sampler2D tex;
|
||||||
|
in vec2 uv;
|
||||||
|
in vec3 worldpos;
|
||||||
|
out vec4 glOutColor;
|
||||||
|
void main(){
|
||||||
|
glOutColor = texture(tex, uv) + vec4(worldpos.z * 0.5);
|
||||||
|
}""",
|
||||||
|
varyings = @[
|
||||||
|
Varying(vtype: Uv, varname: "uv"),
|
||||||
|
Varying(vtype: WorldPosition, varname: "worldpos"),
|
||||||
|
],
|
||||||
|
textures = {
|
||||||
|
"tex": texture,
|
||||||
|
}.toOrderedTable,
|
||||||
|
)
|
||||||
|
|
||||||
|
scene.enable_render()
|
||||||
|
engine.run()
|
Loading…
Reference in a new issue