1 | 1 |
const graphics = @import("graphics.zig");
|
2 | 2 |
|
3 | 3 |
const vertex_source =
|
4 | |
\\struct PSInput
|
5 | |
\\{
|
6 | |
\\ float4 Pos : SV_POSITION;
|
7 | |
\\ float3 Color : COLOR;
|
8 | |
\\};
|
9 | |
\\void main(in uint VertId : SV_VertexID,
|
10 | |
\\ out PSInput PSIn)
|
11 | |
\\{
|
12 | |
\\ float4 Pos[3];
|
13 | |
\\ Pos[0] = float4(-0.5, -0.5, 0.0, 1.0);
|
14 | |
\\ Pos[1] = float4( 0.0, +0.5, 0.0, 1.0);
|
15 | |
\\ Pos[2] = float4(+0.5, -0.5, 0.0, 1.0);
|
16 | |
\\ float3 Col[3];
|
17 | |
\\ Col[0] = float3(1.0, 0.0, 0.0); // red
|
18 | |
\\ Col[1] = float3(0.0, 1.0, 0.0); // green
|
19 | |
\\ Col[2] = float3(0.0, 0.0, 1.0); // blue
|
20 | |
\\ PSIn.Pos = Pos[VertId];
|
21 | |
\\ PSIn.Color = Col[VertId];
|
|
4 |
\\layout(location = 0) out vec3 out_Color;
|
|
5 |
\\
|
|
6 |
\\void main() {
|
|
7 |
\\ vec4 positions[3] = vec4[3](
|
|
8 |
\\ vec4(-0.5, -0.5, 0.0, 1.0),
|
|
9 |
\\ vec4(0.0, 0.5, 0.0, 1.0),
|
|
10 |
\\ vec4(0.5, -0.5, 0.0, 1.0)
|
|
11 |
\\ );
|
|
12 |
\\ vec3 colors[3] = vec3[3](
|
|
13 |
\\ vec3(1.0, 0.0, 0.0),
|
|
14 |
\\ vec3(0.0, 1.0, 0.0),
|
|
15 |
\\ vec3(0.0, 0.0, 1.0)
|
|
16 |
\\ );
|
|
17 |
\\
|
|
18 |
\\ gl_Position = positions[uint(gl_VertexIndex)];
|
|
19 |
\\ out_Color = colors[uint(gl_VertexIndex)];
|
22 | 20 |
\\}
|
23 | 21 |
;
|
24 | 22 |
|
25 | |
const fragment_source =
|
26 | |
\\struct PSInput
|
27 | |
\\{
|
28 | |
\\ float4 Pos : SV_POSITION;
|
29 | |
\\ float3 Color : COLOR;
|
|
23 |
const geometry_source =
|
|
24 |
\\layout(triangles, invocations=2) in;
|
|
25 |
\\layout(max_vertices = 3, triangle_strip) out;
|
|
26 |
\\
|
|
27 |
\\struct VSOutput {
|
|
28 |
\\ vec4 position;
|
|
29 |
\\ vec3 color;
|
30 | 30 |
\\};
|
31 | |
\\float4 main(PSInput In) : SV_Target
|
32 | |
\\{
|
33 | |
\\ return float4(In.Color.rgb, 1.0);
|
|
31 |
\\
|
|
32 |
\\layout(location = 0) out vec3 out_Color;
|
|
33 |
\\layout(location = 0) in vec3 in_Color[3];
|
|
34 |
\\
|
|
35 |
\\void main() {
|
|
36 |
\\ VSOutput triangle[3] = VSOutput[](
|
|
37 |
\\ VSOutput(gl_in[0].gl_Position, in_Color[0]),
|
|
38 |
\\ VSOutput(gl_in[1].gl_Position, in_Color[1]),
|
|
39 |
\\ VSOutput(gl_in[2].gl_Position, in_Color[2])
|
|
40 |
\\ );
|
|
41 |
\\ for (int i = 0; i < 3; i++)
|
|
42 |
\\ {
|
|
43 |
\\ gl_Position = triangle[i].position;
|
|
44 |
\\ out_Color = triangle[i].color;
|
|
45 |
\\ gl_ViewportIndex = int(gl_InvocationID);
|
|
46 |
\\ EmitVertex();
|
|
47 |
\\ }
|
|
48 |
\\ EndPrimitive();
|
34 | 49 |
\\}
|
35 | 50 |
;
|
36 | 51 |
|
|
52 |
const fragment_source =
|
|
53 |
\\layout(location = 0) in vec3 in_Color;
|
|
54 |
\\layout(location = 0) out vec4 out_Color;
|
|
55 |
\\
|
|
56 |
\\void main() {
|
|
57 |
\\ out_Color = vec4(in_Color, 1.0);
|
|
58 |
\\}
|
|
59 |
;
|
|
60 |
|
37 | 61 |
pub const Scene = struct {
|
38 | |
pipeline_state: ?*dg.IPipelineState,
|
39 | |
|
40 | |
graphics: *const graphics.Graphics,
|
41 | |
|
42 | |
pub fn init(gfx: *const graphics.Graphics) !Scene {
|
43 | |
var pipeline_state: ?*dg.IPipelineState = null;
|
44 | |
|
45 | |
const dev = gfx.dg_device;
|
46 | |
const swc = gfx.swapchain.dg_handle;
|
47 | |
|
48 | |
var shader_create_info = dg.ShaderCreateInfo{
|
49 | |
.SourceLanguage = dg.SHADER_SOURCE_LANGUAGE_HLSL,
|
50 | |
.UseCombinedTextureSamplers = true,
|
51 | |
|
52 | |
.Desc = undefined,
|
|
62 |
pipeline_state: *dg.IPipelineState,
|
|
63 |
viewports: []dg.Viewport,
|
|
64 |
scissors: []dg.Rect,
|
|
65 |
|
|
66 |
ctx: dg.IDeviceContext_Wrapper,
|
|
67 |
dev: dg.IRenderDeviceVk_Wrapper,
|
|
68 |
swc: dg.ISwapChainVk_Wrapper,
|
|
69 |
|
|
70 |
fn createShader(
|
|
71 |
self: *const Scene,
|
|
72 |
name: [:0]const u8,
|
|
73 |
shader_type: dg.SHADER_TYPE,
|
|
74 |
language: dg.SHADER_SOURCE_LANGUAGE,
|
|
75 |
source: [:0]const u8,
|
|
76 |
) !*dg.IShader {
|
|
77 |
var shader: ?*dg.IShader = null;
|
|
78 |
self.dev.CreateShader(&dg.ShaderCreateInfo{
|
|
79 |
.Desc = .{
|
|
80 |
._DeviceObjectAttribs = .{ .Name = name },
|
|
81 |
.ShaderType = shader_type,
|
|
82 |
},
|
|
83 |
|
|
84 |
.Source = source,
|
|
85 |
.SourceLanguage = language,
|
53 | 86 |
|
54 | 87 |
// default
|
55 | 88 |
.FilePath = null,
|
56 | 89 |
.pShaderSourceStreamFactory = null,
|
57 | 90 |
.ppConversionStream = null,
|
58 | |
.Source = null,
|
59 | 91 |
.ByteCode = null,
|
60 | 92 |
.ByteCodeSize = 0,
|
61 | 93 |
.EntryPoint = "main",
|
62 | 94 |
.Macros = null,
|
|
95 |
.UseCombinedTextureSamplers = false,
|
63 | 96 |
.CombinedSamplerSuffix = "_sampler",
|
64 | 97 |
.ShaderCompiler = dg.SHADER_COMPILER_DEFAULT,
|
65 | 98 |
.HLSLVersion = .{ .Major = 0, .Minor = 0 },
|
66 | 99 |
.GLSLVersion = .{ .Major = 0, .Minor = 0 },
|
67 | 100 |
.GLESSLVersion = .{ .Major = 0, .Minor = 0 },
|
68 | 101 |
.ppCompilerOutput = null,
|
69 | |
};
|
70 | |
|
71 | |
var vertex_shader: ?*dg.IShader = null;
|
72 | |
var fragment_shader: ?*dg.IShader = null;
|
73 | |
{
|
74 | |
shader_create_info.Desc = .{
|
75 | |
._DeviceObjectAttribs = .{ .Name = "Vertex Shader" },
|
76 | |
.ShaderType = dg.SHADER_TYPE_VERTEX,
|
|
102 |
}, &shader);
|
|
103 |
|
|
104 |
return shader orelse error.ShaderCreationError;
|
|
105 |
}
|
|
106 |
|
|
107 |
pub fn init(gfx: *const graphics.Graphics) !Scene {
|
|
108 |
const dev = gfx.dg_device;
|
|
109 |
const swc = gfx.swapchain.dg_handle;
|
|
110 |
|
|
111 |
var self: Scene = undefined;
|
|
112 |
self.ctx = gfx.dg_ctx;
|
|
113 |
self.dev = dev;
|
|
114 |
self.swc = swc;
|
|
115 |
|
|
116 |
self.viewports = try gfx.allocator.alloc(dg.Viewport, gfx.swapchain.image_rects.len);
|
|
117 |
errdefer gfx.allocator.free(self.viewports);
|
|
118 |
self.scissors = try gfx.allocator.alloc(dg.Rect, gfx.swapchain.image_rects.len);
|
|
119 |
errdefer gfx.allocator.free(self.scissors);
|
|
120 |
|
|
121 |
for (gfx.swapchain.image_rects) |rect, i| {
|
|
122 |
self.viewports[i] = .{
|
|
123 |
.TopLeftX = @intToFloat(f32, rect.offset.x),
|
|
124 |
.TopLeftY = @intToFloat(f32, rect.offset.y),
|
|
125 |
.Width = @intToFloat(f32, rect.extent.width),
|
|
126 |
.Height = @intToFloat(f32, rect.extent.height),
|
|
127 |
.MinDepth = 0,
|
|
128 |
.MaxDepth = 1,
|
77 | 129 |
};
|
78 | |
shader_create_info.Source = vertex_source;
|
79 | |
dev.CreateShader(&shader_create_info, &vertex_shader);
|
|
130 |
|
|
131 |
self.scissors[i] = .{
|
|
132 |
.left = rect.offset.x,
|
|
133 |
.right = rect.offset.x + rect.extent.width,
|
|
134 |
.top = rect.offset.y,
|
|
135 |
.bottom = rect.offset.y + rect.extent.height,
|
|
136 |
};
|
80 | 137 |
}
|
81 | 138 |
|
82 | |
{
|
83 | |
shader_create_info.Desc = .{
|
84 | |
._DeviceObjectAttribs = .{ .Name = "Fragment Shader" },
|
85 | |
.ShaderType = dg.SHADER_TYPE_PIXEL,
|
86 | |
};
|
87 | |
shader_create_info.Source = fragment_source;
|
88 | |
dev.CreateShader(&shader_create_info, &fragment_shader);
|
89 | |
}
|
90 | |
|
|
139 |
const vertex_shader = try self.createShader("Vertex Shader", dg.SHADER_TYPE_VERTEX, dg.SHADER_SOURCE_LANGUAGE_GLSL, vertex_source);
|
|
140 |
const geometry_shader = try self.createShader("Geometry Shader", dg.SHADER_TYPE_GEOMETRY, dg.SHADER_SOURCE_LANGUAGE_GLSL, geometry_source);
|
|
141 |
const fragment_shader = try self.createShader("Fragment Shader", dg.SHADER_TYPE_PIXEL, dg.SHADER_SOURCE_LANGUAGE_GLSL, fragment_source);
|
|
142 |
|
|
143 |
var pipeline_state: ?*dg.IPipelineState = null;
|
91 | 144 |
dev.CreateGraphicsPipelineState(&dg.GraphicsPipelineStateCreateInfo{
|
92 | 145 |
._PipelineStateCreateInfo = .{
|
93 | 146 |
.PSODesc = .{
|
|
109 | 162 |
},
|
110 | 163 |
.GraphicsPipeline = .{
|
111 | 164 |
.PrimitiveTopology = dg.PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
112 | |
.NumViewports = 1,
|
|
165 |
.NumViewports = 2,
|
113 | 166 |
.NumRenderTargets = 1, // non default
|
114 | 167 |
.SubpassIndex = 0,
|
115 | 168 |
.pRenderPass = null,
|
|
153 | 206 |
.CullMode = dg.CULL_MODE_NONE, // not default
|
154 | 207 |
.FrontCounterClockwise = true,
|
155 | 208 |
.DepthClipEnable = true,
|
156 | |
.ScissorEnable = false,
|
|
209 |
.ScissorEnable = true,
|
157 | 210 |
.AntialiasedLineEnable = false,
|
158 | 211 |
.DepthBias = 0,
|
159 | 212 |
.DepthBiasClamp = 0,
|
|
178 | 231 |
.pPS = fragment_shader,
|
179 | 232 |
.pDS = null,
|
180 | 233 |
.pHS = null,
|
181 | |
.pGS = null,
|
|
234 |
.pGS = geometry_shader,
|
182 | 235 |
.pAS = null,
|
183 | 236 |
.pMS = null,
|
184 | 237 |
}, &pipeline_state);
|
185 | |
|
186 | |
return Scene{
|
187 | |
.pipeline_state = pipeline_state orelse return error.PipelineError,
|
188 | |
|
189 | |
.graphics = gfx,
|
190 | |
};
|
|
238 |
self.pipeline_state = pipeline_state orelse return error.PipelineCreateError;
|
|
239 |
|
|
240 |
return self;
|
|
241 |
}
|
|
242 |
|
|
243 |
pub fn deinit(self: *const Scene) void {
|
|
244 |
gfx.allocator.free(self.viewports);
|
191 | 245 |
}
|
192 | 246 |
|
193 | 247 |
pub fn render(self: *const Scene) !void {
|
194 | |
const ctx = self.graphics.dg_ctx;
|
195 | |
const swc = self.graphics.swapchain.dg_handle;
|
196 | |
|
197 | |
var rtv = swc.GetCurrentBackBufferRTV();
|
198 | |
const dsv = swc.GetDepthBufferDSV();
|
199 | |
ctx.SetRenderTargets(1, &rtv, dsv, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
248 |
var rtv = self.swc.GetCurrentBackBufferRTV();
|
|
249 |
const dsv = self.swc.GetDepthBufferDSV();
|
|
250 |
|
|
251 |
self.ctx.SetRenderTargets(1, &rtv, dsv, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
252 |
self.ctx.SetViewports(
|
|
253 |
@intCast(u32, self.viewports.len),
|
|
254 |
self.viewports.ptr,
|
|
255 |
0,
|
|
256 |
0,
|
|
257 |
);
|
|
258 |
self.ctx.SetScissorRects(
|
|
259 |
@intCast(u32, self.scissors.len),
|
|
260 |
self.scissors.ptr,
|
|
261 |
0,
|
|
262 |
0,
|
|
263 |
);
|
200 | 264 |
|
201 | 265 |
const clear_color = [_]f32{ 0.35, 0.35, 0.35, 1 };
|
202 | |
ctx.ClearRenderTarget(rtv, clear_color[0..], dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
203 | |
ctx.ClearDepthStencil(dsv, dg.CLEAR_DEPTH_FLAG, 1, 0, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
204 | |
|
205 | |
ctx.SetPipelineState(self.pipeline_state);
|
206 | |
|
207 | |
ctx.Draw(&dg.DrawAttribs{
|
|
266 |
self.ctx.ClearRenderTarget(rtv, clear_color[0..], dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
267 |
self.ctx.ClearDepthStencil(dsv, dg.CLEAR_DEPTH_FLAG, 1, 0, dg.RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
|
|
268 |
|
|
269 |
self.ctx.SetPipelineState(self.pipeline_state);
|
|
270 |
|
|
271 |
self.ctx.Draw(&dg.DrawAttribs{
|
208 | 272 |
.NumVertices = 3,
|
209 | 273 |
|
210 | 274 |
.Flags = dg.DRAW_FLAG_NONE,
|