use anyhow::Result;
use cgmath::{Matrix4, Vector3};
use super::{CommandBufferBuilder, VulkanContext, VulkanWindow};
pub(crate) mod cube_geometry;
pub(crate) mod egui_adapter;
pub(crate) mod flat_texture;
pub(crate) mod vert_3d {
vulkano_shaders::shader! {
shaders: {
cube_geometry: {
ty: "vertex",
src: r"
#version 460
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 uv_texcoord;
layout(location = 3) in float brightness;
layout(location = 4) in float global_brightness_contribution;
layout(location = 5) in float wave_horizontal;
layout(set = 1, binding = 0) uniform UniformData {
mat4 vp_matrix;
vec2 plant_wave_vector;
vec3 global_brightness_color;
vec3 global_light_direction;
};
// 64 bytes of push constants :(
layout(push_constant) uniform ModelMatrix {
mat4 model_matrix;
};
layout(location = 0) out vec2 uv_texcoord_out;
layout(location = 1) out float brightness_out;
layout(location = 2) out vec3 global_brightness_out;
void main() {
float wave_x = wave_horizontal * plant_wave_vector.x;
float wave_z = wave_horizontal * plant_wave_vector.y;
vec3 position_with_wave = vec3(position.x + wave_x, position.y, position.z + wave_z);
gl_Position = vp_matrix * model_matrix * vec4(position_with_wave, 1.0);
uv_texcoord_out = uv_texcoord;
brightness_out = brightness;
float gbc_adjustment = 0.5 + 0.5 * max(0, dot(global_light_direction, normal));
global_brightness_out = global_brightness_color * global_brightness_contribution * gbc_adjustment;
}
"
},
}
}
impl From<cgmath::Matrix4<f32>> for ModelMatrix {
fn from(value: cgmath::Matrix4<f32>) -> Self {
ModelMatrix {
model_matrix: value.into(),
}
}
}
}
pub(crate) mod frag_lighting {
vulkano_shaders::shader! {
ty: "fragment",
src: r"
#version 460
layout(location = 0) in vec2 uv_texcoord;
layout(location = 1) in float brightness;
layout(location = 2) in vec3 global_brightness;
layout(location = 0) out vec4 f_color;
layout(set = 0, binding = 0) uniform sampler2D tex;
void main() {
vec4 color = texture(tex, uv_texcoord);
f_color = vec4((brightness + global_brightness.r) * color.r,
(brightness + global_brightness.g) * color.g,
(brightness + global_brightness.b) * color.b,
color.a);
}
"
}
}
pub(crate) mod frag_lighting_sparse {
vulkano_shaders::shader! {
ty: "fragment",
src: r"
#version 460
layout(location = 0) in vec2 uv_texcoord;
layout(location = 1) in float brightness;
layout(location = 2) in vec3 global_brightness;
layout(location = 0) out vec4 f_color;
layout(set = 0, binding = 0) uniform sampler2D tex;
void main() {
vec4 color = texture(tex, uv_texcoord);
f_color = vec4((brightness + global_brightness.r) * color.r,
(brightness + global_brightness.g) * color.g,
(brightness + global_brightness.b) * color.b,
color.a);
if (f_color.a < 0.5) {
discard;
} else {
f_color.a = 1.0;
}
}
"
}
}
pub(crate) mod vert_2d {
vulkano_shaders::shader! {
shaders: {
flat_tex: {
ty: "vertex",
src: r"
#version 460
layout(location = 0) in vec2 position;
layout(location = 1) in vec2 uv_texcoord;
layout(set = 1, binding = 0) uniform UniformData {
vec2 device_w_h;
};
layout(location = 0) out vec2 uv_texcoord_out;
void main() {
// pixel -> normalized device coordinates
vec2 ndc = (2.0 * position + 1) / device_w_h - 1.0;
// Z shouldn't matter (no depth test)
gl_Position = vec4(ndc, 0.5, 1.0);
uv_texcoord_out = uv_texcoord;
}
"
}
}
}
}
pub(crate) mod frag_simple {
vulkano_shaders::shader! {
ty: "fragment",
src: r"
#version 460
layout(location = 0) in vec2 uv_texcoord;
layout(location = 0) out vec4 f_color;
layout(set = 0, binding = 0) uniform sampler2D tex;
void main() {
f_color = texture(tex, uv_texcoord);
}
"
}
}
pub(crate) trait PipelineWrapper<T, U> {
type PassIdentifier;
fn draw<L>(
&mut self,
builder: &mut CommandBufferBuilder<L>,
draw_calls: T,
pass: Self::PassIdentifier,
) -> Result<()>;
fn bind<L>(
&mut self,
ctx: &VulkanContext,
per_frame_config: U,
command_buf_builder: &mut CommandBufferBuilder<L>,
pass: Self::PassIdentifier,
) -> Result<()>;
}
pub(crate) trait PipelineProvider
where
Self: Sized,
{
type DrawCall<'a>
where
Self: 'a;
type PerPipelineConfig<'a>
where
Self: 'a;
type PerFrameConfig;
type PipelineWrapperImpl: for<'a> PipelineWrapper<Self::DrawCall<'a>, Self::PerFrameConfig>;
fn make_pipeline(
&self,
ctx: &VulkanWindow,
config: Self::PerPipelineConfig<'_>,
) -> Result<Self::PipelineWrapperImpl>;
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct SceneState {
pub(crate) vp_matrix: Matrix4<f32>,
pub(crate) global_light_color: [f32; 3],
pub(crate) clear_color: [f32; 4],
pub(crate) global_light_direction: Vector3<f32>,
}