blob: c2c6c303ae96431b4c2de1593a31ecd4a753ca1e [file] [log] [blame]
Austin Eng376f1c62017-05-30 20:03:44 -04001// Copyright 2017 The NXT Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "Utils.h"
16
17#include <vector>
18#include <glm/glm/glm.hpp>
19#include <glm/glm/gtc/matrix_transform.hpp>
20#include <glm/glm/gtc/type_ptr.hpp>
21
22nxt::Device device;
23
24nxt::Buffer indexBuffer;
25nxt::Buffer vertexBuffer;
26nxt::Buffer planeBuffer;
27nxt::Buffer cameraBuffer;
28nxt::Buffer transformBuffer[2];
29
30nxt::BindGroup cameraBindGroup;
31nxt::BindGroup bindGroup[2];
32nxt::BindGroup cubeTransformBindGroup[2];
33
34nxt::Queue queue;
35nxt::Pipeline pipeline;
36nxt::Pipeline planePipeline;
37nxt::Pipeline reflectionPipeline;
38nxt::RenderPass renderpass;
39nxt::Framebuffer framebuffer;
40
41void initBuffers() {
42 static const uint32_t indexData[6*6] = {
43 0, 1, 2,
44 0, 2, 3,
45
46 4, 5, 6,
47 4, 6, 7,
48
49 8, 9, 10,
50 8, 10, 11,
51
52 12, 13, 14,
53 12, 14, 15,
54
55 16, 17, 18,
56 16, 18, 19,
57
58 20, 21, 22,
59 20, 22, 23
60 };
61 indexBuffer = device.CreateBufferBuilder()
62 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Index)
63 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
64 .SetSize(sizeof(indexData))
65 .GetResult();
66 indexBuffer.SetSubData(0, sizeof(indexData) / sizeof(uint32_t), indexData);
67 indexBuffer.FreezeUsage(nxt::BufferUsageBit::Index);
68
69 static const float vertexData[6 * 4 * 6] = {
70 -1.0, -1.0, 1.0, 1.0, 0.0, 0.0,
71 1.0, -1.0, 1.0, 1.0, 0.0, 0.0,
72 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
73 -1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
74
75 -1.0, -1.0, -1.0, 1.0, 1.0, 0.0,
76 -1.0, 1.0, -1.0, 1.0, 1.0, 0.0,
77 1.0, 1.0, -1.0, 1.0, 1.0, 0.0,
78 1.0, -1.0, -1.0, 1.0, 1.0, 0.0,
79
80 -1.0, 1.0, -1.0, 1.0, 0.0, 1.0,
81 -1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
82 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
83 1.0, 1.0, -1.0, 1.0, 0.0, 1.0,
84
85 -1.0, -1.0, -1.0, 0.0, 1.0, 0.0,
86 1.0, -1.0, -1.0, 0.0, 1.0, 0.0,
87 1.0, -1.0, 1.0, 0.0, 1.0, 0.0,
88 -1.0, -1.0, 1.0, 0.0, 1.0, 0.0,
89
90 1.0, -1.0, -1.0, 0.0, 1.0, 1.0,
91 1.0, 1.0, -1.0, 0.0, 1.0, 1.0,
92 1.0, 1.0, 1.0, 0.0, 1.0, 1.0,
93 1.0, -1.0, 1.0, 0.0, 1.0, 1.0,
94
95 -1.0, -1.0, -1.0, 1.0, 1.0, 1.0,
96 -1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
97 -1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
98 -1.0, 1.0, -1.0, 1.0, 1.0, 1.0
99 };
100
101 vertexBuffer = device.CreateBufferBuilder()
102 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
103 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
104 .SetSize(sizeof(vertexData))
105 .GetResult();
106 vertexBuffer.SetSubData(0, sizeof(vertexData) / sizeof(uint32_t),
107 reinterpret_cast<const uint32_t*>(vertexData));
108 vertexBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
109
110 static const float planeData[6 * 4] = {
111 -2.0, -1.0, -2.0, 0.5, 0.5, 0.5,
112 2.0, -1.0, -2.0, 0.5, 0.5, 0.5,
113 2.0, -1.0, 2.0, 0.5, 0.5, 0.5,
114 -2.0, -1.0, 2.0, 0.5, 0.5, 0.5,
115 };
116
117 planeBuffer = device.CreateBufferBuilder()
118 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
119 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
120 .SetSize(sizeof(planeData))
121 .GetResult();
122 planeBuffer.SetSubData(0, sizeof(planeData) / sizeof(uint32_t),
123 reinterpret_cast<const uint32_t*>(planeData));
124 planeBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
125}
126
127struct {
128 glm::mat4 view;
129 glm::mat4 proj;
130} cameraData;
131
132void init() {
133 device = CreateCppNXTDevice();
134
135 queue = device.CreateQueueBuilder().GetResult();
136
137 initBuffers();
138
139 nxt::ShaderModule vsModule = CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
140 #version 450
141 layout(set = 0, binding = 0) uniform cameraData {
142 mat4 view;
143 mat4 proj;
144 } camera;
145 layout(set = 0, binding = 1) uniform modelData {
146 mat4 modelMatrix;
147 };
148 layout(location = 0) in vec3 pos;
149 layout(location = 1) in vec3 col;
150 layout(location = 2) out vec3 f_col;
151 void main() {
152 f_col = col;
153 gl_Position = camera.proj * camera.view * modelMatrix * vec4(pos, 1.0);
154 })"
155 );
156
157 nxt::ShaderModule fsModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
158 #version 450
159 layout(location = 2) in vec3 f_col;
160 out vec4 fragColor;
161 void main() {
162 fragColor = vec4(f_col, 1.0);
163 })"
164 );
165
166 nxt::ShaderModule fsReflectionModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
167 #version 450
168 layout(location = 2) in vec3 f_col;
169 out vec4 fragColor;
170 void main() {
171 fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
172 })"
173 );
174
175 auto inputState = device.CreateInputStateBuilder()
176 .SetAttribute(0, 0, nxt::VertexFormat::FloatR32G32B32, 0)
177 .SetAttribute(1, 0, nxt::VertexFormat::FloatR32G32B32, 3 * sizeof(float))
178 .SetInput(0, 6 * sizeof(float), nxt::InputStepMode::Vertex)
Austin Eng376f1c62017-05-30 20:03:44 -0400179 .GetResult();
180
181 nxt::BindGroupLayout bgl = device.CreateBindGroupLayoutBuilder()
182 .SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2)
183 .GetResult();
184
185 nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
186 .SetBindGroupLayout(0, bgl)
187 .GetResult();
188
189 cameraBuffer = device.CreateBufferBuilder()
190 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
191 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
192 .SetSize(sizeof(cameraData))
193 .GetResult();
194
195 glm::mat4 transform(1.0);
196
197 transformBuffer[0] = device.CreateBufferBuilder()
198 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
199 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
200 .SetSize(sizeof(glm::mat4))
201 .GetResult();
202 transformBuffer[0].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
203 transformBuffer[0].FreezeUsage(nxt::BufferUsageBit::Uniform);
204
205 transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f));
206
207 transformBuffer[1] = device.CreateBufferBuilder()
208 .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
209 .SetInitialUsage(nxt::BufferUsageBit::Mapped)
210 .SetSize(sizeof(glm::mat4))
211 .GetResult();
212 transformBuffer[1].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
213 transformBuffer[1].FreezeUsage(nxt::BufferUsageBit::Uniform);
214
215 nxt::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder()
216 .SetExtent(0, sizeof(cameraData))
217 .GetResult();
218
219 nxt::BufferView transformBufferView[2] = {
220 transformBuffer[0].CreateBufferViewBuilder()
221 .SetExtent(0, sizeof(glm::mat4))
222 .GetResult(),
223 transformBuffer[1].CreateBufferViewBuilder()
224 .SetExtent(0, sizeof(glm::mat4))
225 .GetResult(),
226 };
227
228 bindGroup[0] = device.CreateBindGroupBuilder()
229 .SetLayout(bgl)
230 .SetUsage(nxt::BindGroupUsage::Frozen)
231 .SetBufferViews(0, 1, &cameraBufferView)
232 .SetBufferViews(1, 1, &transformBufferView[0])
233 .GetResult();
234
235 bindGroup[1] = device.CreateBindGroupBuilder()
236 .SetLayout(bgl)
237 .SetUsage(nxt::BindGroupUsage::Frozen)
238 .SetBufferViews(0, 1, &cameraBufferView)
239 .SetBufferViews(1, 1, &transformBufferView[1])
240 .GetResult();
241
242 CreateDefaultRenderPass(device, &renderpass, &framebuffer);
243
244 auto depthStencilState = device.CreateDepthStencilStateBuilder()
Austin Eng10634392017-06-01 11:30:03 -0400245 .SetDepthCompareFunction(nxt::CompareFunction::Less)
246 .SetDepthWriteEnabled(true)
Austin Eng376f1c62017-05-30 20:03:44 -0400247 .GetResult();
248
249 pipeline = device.CreatePipelineBuilder()
250 .SetSubpass(renderpass, 0)
251 .SetLayout(pl)
252 .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
253 .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
254 .SetInputState(inputState)
255 .SetDepthStencilState(depthStencilState)
256 .GetResult();
257
258 auto planeStencilState = device.CreateDepthStencilStateBuilder()
Austin Eng10634392017-06-01 11:30:03 -0400259 .SetDepthCompareFunction(nxt::CompareFunction::Less)
260 .SetDepthWriteEnabled(false)
261 .SetStencilFunction(nxt::Face::Both, nxt::CompareFunction::Always, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
Austin Eng376f1c62017-05-30 20:03:44 -0400262 .GetResult();
263
264 planePipeline = device.CreatePipelineBuilder()
265 .SetSubpass(renderpass, 0)
266 .SetLayout(pl)
267 .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
268 .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
269 .SetInputState(inputState)
270 .SetDepthStencilState(planeStencilState)
271 .GetResult();
272
273 auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
Austin Eng10634392017-06-01 11:30:03 -0400274 .SetDepthCompareFunction(nxt::CompareFunction::Less)
275 .SetDepthWriteEnabled(true)
276 .SetStencilFunction(nxt::Face::Both, nxt::CompareFunction::Equal, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
Austin Eng376f1c62017-05-30 20:03:44 -0400277 .GetResult();
278
279 reflectionPipeline = device.CreatePipelineBuilder()
280 .SetSubpass(renderpass, 0)
281 .SetLayout(pl)
282 .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
283 .SetStage(nxt::ShaderStage::Fragment, fsReflectionModule, "main")
284 .SetInputState(inputState)
285 .SetDepthStencilState(reflectionStencilState)
286 .GetResult();
287
288 cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
289}
290
291struct {uint32_t a; float b;} s;
292void frame() {
293 s.a = (s.a + 1) % 256;
294 s.b += 0.01;
295 if (s.b >= 1.0f) {s.b = 0.0f;}
296 static const uint32_t vertexBufferOffsets[1] = {0};
297
298 cameraData.view = glm::lookAt(
299 glm::vec3(8.f * std::sin(glm::radians(s.b * 360.f)), 2.f, 8.f * std::cos(glm::radians(s.b * 360.f))),
300 glm::vec3(0.0f, 0.0f, 0.0f),
301 glm::vec3(0.0f, 1.0f, 0.0f)
302 );
303
304 cameraBuffer.TransitionUsage(nxt::BufferUsageBit::Mapped);
305 cameraBuffer.SetSubData(0, sizeof(cameraData) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&cameraData));
306
307 nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
308 .BeginRenderPass(renderpass, framebuffer)
309 .SetPipeline(pipeline)
310 .TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform)
311 .SetBindGroup(0, bindGroup[0])
312 .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
313 .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32)
314 .DrawElements(36, 1, 0, 0)
315
Austin Eng10634392017-06-01 11:30:03 -0400316 .SetStencilReference(0x1)
Austin Eng376f1c62017-05-30 20:03:44 -0400317 .SetPipeline(planePipeline)
Austin Eng376f1c62017-05-30 20:03:44 -0400318 .SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets)
319 .DrawElements(6, 1, 0, 0)
320
321 .SetPipeline(reflectionPipeline)
Austin Eng376f1c62017-05-30 20:03:44 -0400322 .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
323 .SetBindGroup(0, bindGroup[1])
324 .DrawElements(36, 1, 0, 0)
325 .EndRenderPass()
326 .GetResult();
327
328 queue.Submit(1, &commands);
329 DoSwapBuffers();
330}
331
332int main(int argc, const char* argv[]) {
333 if (!InitUtils(argc, argv)) {
334 return 1;
335 }
336 init();
337
338 while (!ShouldQuit()) {
339 frame();
340 USleep(16000);
341 }
342
343 // TODO release stuff
344}