use anyhow::Result;
use super::{CommandBufferBuilder, VulkanContext};
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 vec2 uv_texcoord;
layout(location = 2) in float brightness;
layout(location = 3) in float global_brightness_contribution;
layout(location = 4) in float wave_horizontal;
layout(set = 1, binding = 0) uniform UniformData {
mat4 vp_matrix;
vec2 plant_wave_vector;
float global_brightness;
};
// 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;
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 + (global_brightness * global_brightness_contribution);
}
"
},
}
}
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 = 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 * color.r, brightness * color.g, brightness * 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 = 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 * color.r, brightness * color.g, brightness * 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: &VulkanContext,
config: Self::PerPipelineConfig<'_>,
) -> Result<Self::PipelineWrapperImpl>;
}