Mercurial > games > semicongine
comparison examples/E02_squares.nim @ 136:fc5db4f1f94e
did: rewrite example 02 with new engine approach
author | Sam <sam@basx.dev> |
---|---|
date | Thu, 20 Apr 2023 23:46:22 +0700 |
parents | 779607656b12 |
children | ac2b6777c5db |
comparison
equal
deleted
inserted
replaced
135:250e1dcbfec9 | 136:fc5db4f1f94e |
---|---|
1 import std/times | 1 import std/times |
2 import std/sequtils | |
2 import std/strutils | 3 import std/strutils |
3 import std/math | 4 import std/math |
4 import std/random | 5 import std/random |
5 | 6 |
6 import semicongine | 7 import semicongine |
7 | 8 |
8 type | |
9 VertexDataA = object | |
10 position11: PositionAttribute[Vec2] | |
11 color22: ColorAttribute[Vec3] | |
12 index: GenericAttribute[uint32] | |
13 Uniforms = object | |
14 t: Descriptor[float32] | |
15 | |
16 var | |
17 pipeline: RenderPipeline[VertexDataA, Uniforms] | |
18 uniformdata = Uniforms(t: Descriptor[float32](value: 0'f32)) | |
19 | |
20 proc globalUpdate(engine: var Engine, t, dt: float32) = | |
21 uniformdata.t.value += dt | |
22 engine.vulkan.device.updateUniformData(pipeline, uniformdata) | |
23 | 9 |
24 when isMainModule: | 10 when isMainModule: |
25 randomize() | 11 randomize() |
26 var myengine = igniteEngine("Squares") | |
27 const | 12 const |
28 COLUMNS = 10 | 13 COLUMNS = 10 |
29 ROWS = 10 | 14 ROWS = 10 |
30 WIDTH = 2'f32 / COLUMNS | 15 WIDTH = 2'f32 / COLUMNS |
31 HEIGHT = 2'f32 / ROWS | 16 HEIGHT = 2'f32 / ROWS |
32 var | 17 var |
33 vertices: array[COLUMNS * ROWS * 4, Vec2] | 18 vertices: array[COLUMNS * ROWS * 4, Vec3f] |
34 colors: array[COLUMNS * ROWS * 4, Vec3] | 19 colors: array[COLUMNS * ROWS * 4, Vec3f] |
35 iValues: array[COLUMNS * ROWS * 4, uint32] | 20 iValues: array[COLUMNS * ROWS * 4, uint32] |
36 indices: array[COLUMNS * ROWS * 2, array[3, uint16]] | 21 indices: array[COLUMNS * ROWS * 2, array[3, uint16]] |
37 | 22 |
38 for row in 0 ..< ROWS: | 23 for row in 0 ..< ROWS: |
39 for col in 0 ..< COLUMNS: | 24 for col in 0 ..< COLUMNS: |
40 let | 25 let |
41 y: float32 = (row * 2 / COLUMNS) - 1 | 26 y: float32 = (row * 2 / COLUMNS) - 1 |
42 x: float32 = (col * 2 / ROWS) - 1 | 27 x: float32 = (col * 2 / ROWS) - 1 |
43 color = Vec3([(x + 1) / 2, (y + 1) / 2, 0'f32]) | 28 color = Vec3f([(x + 1) / 2, (y + 1) / 2, 0'f32]) |
44 squareIndex = row * COLUMNS + col | 29 squareIndex = row * COLUMNS + col |
45 vertIndex = squareIndex * 4 | 30 vertIndex = squareIndex * 4 |
46 vertices[vertIndex + 0] = Vec2([x, y]) | 31 vertices[vertIndex + 0] = newVec3f(x, y) |
47 vertices[vertIndex + 1] = Vec2([x + WIDTH, y]) | 32 vertices[vertIndex + 1] = newVec3f(x + WIDTH, y) |
48 vertices[vertIndex + 2] = Vec2([x + WIDTH, y + HEIGHT]) | 33 vertices[vertIndex + 2] = newVec3f(x + WIDTH, y + HEIGHT) |
49 vertices[vertIndex + 3] = Vec2([x, y + HEIGHT]) | 34 vertices[vertIndex + 3] = newVec3f(x, y + HEIGHT) |
50 colors[vertIndex + 0] = color | 35 colors[vertIndex + 0] = color |
51 colors[vertIndex + 1] = color | 36 colors[vertIndex + 1] = color |
52 colors[vertIndex + 2] = color | 37 colors[vertIndex + 2] = color |
53 colors[vertIndex + 3] = color | 38 colors[vertIndex + 3] = color |
54 iValues[vertIndex + 0] = uint32(squareIndex) | 39 iValues[vertIndex + 0] = uint32(squareIndex) |
55 iValues[vertIndex + 1] = uint32(squareIndex) | 40 iValues[vertIndex + 1] = uint32(squareIndex) |
56 iValues[vertIndex + 2] = uint32(squareIndex) | 41 iValues[vertIndex + 2] = uint32(squareIndex) |
57 iValues[vertIndex + 3] = uint32(squareIndex) | 42 iValues[vertIndex + 3] = uint32(squareIndex) |
58 indices[squareIndex * 2 + 0] = [uint16(vertIndex + 0), uint16(vertIndex + | 43 indices[squareIndex * 2 + 0] = [uint16(vertIndex + 0), uint16(vertIndex + 1), uint16(vertIndex + 2)] |
59 1), uint16(vertIndex + 2)] | 44 indices[squareIndex * 2 + 1] = [uint16(vertIndex + 2), uint16(vertIndex + 3), uint16(vertIndex + 0)] |
60 indices[squareIndex * 2 + 1] = [uint16(vertIndex + 2), uint16(vertIndex + | |
61 3), uint16(vertIndex + 0)] | |
62 | 45 |
63 | 46 |
64 type PIndexedMesh = Mesh[VertexDataA, | 47 const |
65 uint16] # required so we can use ctor with ref/on heap | 48 vertexInput = @[ |
66 var squaremesh = PIndexedMesh( | 49 attr[Vec3f]("position", memoryLocation=VRAM), |
67 vertexData: VertexDataA( | 50 attr[Vec3f]("color", memoryLocation=VRAM), # TODO: VRAMVisible |
68 position11: PositionAttribute[Vec2](data: @vertices), | 51 attr[uint32]("index", memoryLocation=VRAM), |
69 color22: ColorAttribute[Vec3](data: @colors), | 52 ] |
70 index: GenericAttribute[uint32](data: @iValues), | 53 vertexOutput = @[attr[Vec3f]("outcolor")] |
71 ), | 54 uniforms = @[attr[float32]("time")] |
72 indexed: true, | 55 fragOutput = @[attr[Vec4f]("color")] |
73 indices: @indices | 56 vertexCode = compileGlslShader( |
57 stage=VK_SHADER_STAGE_VERTEX_BIT, | |
58 inputs=vertexInput, | |
59 uniforms=uniforms, | |
60 outputs=vertexOutput, | |
61 main=""" | |
62 float pos_weight = index / 100.0; // add some gamma correction? | |
63 float t = sin(Uniforms.time * 0.5) * 0.5 + 0.5; | |
64 float v = min(1, max(0, pow(pos_weight - t, 2))); | |
65 v = pow(1 - v, 3000); | |
66 outcolor = vec3(color.r, color.g, v * 0.5); | |
67 gl_Position = vec4(position, 1.0); | |
68 """ | |
69 ) | |
70 fragmentCode = compileGlslShader( | |
71 stage=VK_SHADER_STAGE_FRAGMENT_BIT, | |
72 inputs=vertexOutput, | |
73 uniforms=uniforms, | |
74 outputs=fragOutput, | |
75 main="color = vec4(outcolor, 1);" | |
76 ) | |
77 var squaremesh = newMesh( | |
78 positions=vertices, | |
79 indices=indices, | |
80 colors=colors, | |
74 ) | 81 ) |
75 var scene = newThing("scene", newThing("squares", squaremesh)) | 82 setMeshData[uint32](squaremesh, "index", iValues.toSeq) |
76 | 83 |
77 const vertexShader = generateVertexShaderCode[VertexDataA, Uniforms]( | 84 var myengine = initEngine("Squares") |
78 """ | 85 myengine.setRenderer(myengine.gpuDevice.simpleForwardRenderPass(vertexCode, fragmentCode)) |
79 float pos_weight = index / 100.0; // add some gamma correction? | 86 |
80 float t = sin(uniforms.t * 0.5) * 0.5 + 0.5; | 87 var scene = newEntity("scene", newEntity("squares", squaremesh)) |
81 float v = min(1, max(0, pow(pos_weight - t, 2))); | 88 myengine.addScene(scene, vertexInput) |
82 v = pow(1 - v, 3000); | 89 var time = initShaderGlobal("time", 0.0'f32) |
83 out_color = vec4(in_color.r, in_color.g, v * 0.5, 1.0); | 90 scene.components.add time |
84 """ | 91 while myengine.running and not myengine.keyWasPressed(Escape): |
85 ) | 92 myengine.updateInputs() |
86 const fragmentShader = generateFragmentShaderCode[VertexDataA]() | 93 setValue[float32](time.value, get[float32](time.value) + 0.0005) |
87 static: | 94 myengine.renderScene(scene) |
88 echo vertexShader | 95 |
89 pipeline = setupPipeline[VertexDataA, Uniforms, uint16]( | 96 myengine.destroy() |
90 myengine, | |
91 scene, | |
92 vertexShader, | |
93 fragmentShader | |
94 ) | |
95 myengine.run(pipeline, globalUpdate) | |
96 pipeline.trash() | |
97 myengine.trash() |