diff --git a/and_proj/app/src/main/assets/assets/fonts/Roboto-Regular.ttf b/and_proj/app/src/main/assets/assets/fonts/Roboto-Regular.ttf new file mode 100644 index 0000000..2c97eea Binary files /dev/null and b/and_proj/app/src/main/assets/assets/fonts/Roboto-Regular.ttf differ diff --git a/and_proj/app/src/main/assets/assets/fonts/RobotoMono-Regular.ttf b/and_proj/app/src/main/assets/assets/fonts/RobotoMono-Regular.ttf new file mode 100644 index 0000000..d33a4ee Binary files /dev/null and b/and_proj/app/src/main/assets/assets/fonts/RobotoMono-Regular.ttf differ diff --git a/and_proj/app/src/main/assets/assets/scenes/textured_unit_cube.gltf b/and_proj/app/src/main/assets/assets/scenes/textured_unit_cube.gltf new file mode 100644 index 0000000..03553e3 --- /dev/null +++ b/and_proj/app/src/main/assets/assets/scenes/textured_unit_cube.gltf @@ -0,0 +1,120 @@ +{ + "accessors" : [ + { + "bufferView" : 0, + "componentType" : 5126, + "count" : 24, + "type" : "VEC3" + }, + { + "bufferView" : 1, + "componentType" : 5126, + "count" : 24, + "max" : [ + 1, + 1, + 1 + ], + "min" : [ + -1, + -1, + -1 + ], + "type" : "VEC3" + }, + { + "bufferView" : 2, + "componentType" : 5126, + "count" : 24, + "type" : "VEC4" + }, + { + "bufferView" : 3, + "componentType" : 5126, + "count" : 24, + "type" : "VEC2" + }, + { + "bufferView" : 4, + "componentType" : 5121, + "count" : 36, + "type" : "SCALAR" + } + ], + "asset" : { + "generator" : "Khronos Blender glTF 2.0 I/O", + "version" : "2.0" + }, + "bufferViews" : [ + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 0 + }, + { + "buffer" : 0, + "byteLength" : 288, + "byteOffset" : 288 + }, + { + "buffer" : 0, + "byteLength" : 384, + "byteOffset" : 576 + }, + { + "buffer" : 0, + "byteLength" : 192, + "byteOffset" : 960 + }, + { + "buffer" : 0, + "byteLength" : 36, + "byteOffset" : 1152 + } + ], + "buffers" : [ + { + "byteLength" : 1188, + "uri" : "data:application/octet-stream;base64,AACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AACAPwAAAAAAAACAAACAPwAAAAAAAACAAACAPwAAAAAAAACAAAAAgAAAAIAAAIA/AAAAgAAAAIAAAIA/AAAAgAAAAIAAAIA/AAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AACAPwAAAIAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgL8AAACAAAAAAAAAgD8AAACAAACAvwAAgD8AAIC/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAPwAAgD8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAvwAAgD8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAPwAAgD8AAIC/AACAvwAAgD8AAIA/AACAPwAAgD8AAIA/AACAvwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIA/AACAvwAAgL8AAIA/AACAPwAAgL8AAIC/AACAvwAAgD8AAIC/AAAAAAAAAAAAAIC/AACAvwAAAAAAAAAAAACAvwAAgL8AAAAAAAAAAAAAgL8AAIC/AACAPwAAAAAAAACAAACAvwAAgD8AAAAAAAAAgAAAgL8AAIA/AAAAAAAAAIAAAIC/AAAAAAAAAAAAAIC/AACAPwAAAAAAAAAAAACAvwAAgD8AAAAAAAAAAAAAgL8AAIA/AACAPwAAAAAAAACAAACAPwAAgD8AAAAAAAAAgAAAgD8AAIA/AAAAAAAAAIAAAIA/AACAPwAAAAAAAACAAACAvwAAgD8AAAAAAAAAgAAAgL8AAIA/AAAAAAAAAIAAAIC/AACAPwAAAAAAAACAAACAPwAAgD8AAAAAAAAAgAAAgD8AAIA/AAAAAAAAAIAAAIA/AAAAAAAAAAAAAIC/AACAvwAAgD8AAAAAAAAAgAAAgL8AAAAAAAAAAAAAgL8AAIA/AACAPwAAAAAAAACAAACAPwAAgD8AAAAAAAAAgAAAgL8AAIA/AAAAAAAAAIAAAIA/AAAAAAAAgD8AAIC/AAAAQAAAgL8AAIA/AAAAAAAAgD8AAIC/AAAAQAAAgL8AAIA/AAAAAAAAgD8AAIA/AAAAQAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAQAAAgD8AAIA/AAAAAAAAgD8AAIA/AAAAQAAAAAAAAABAAAAAAAAAgD8AAIC/AAAAQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAEAAAIA/AACAPwAAgL8AAIA/AAECAwQFBgcICQoLDA0ODxARABIBAxMEBhQHCRUKDBYNDxcQ" + } + ], + "extensions" : {}, + "materials" : [ + { + "name" : "Material", + "pbrMetallicRoughness" : {} + } + ], + "meshes" : [ + { + "name" : "Cube.001", + "primitives" : [ + { + "attributes" : { + "NORMAL" : 0, + "POSITION" : 1, + "TANGENT" : 2, + "TEXCOORD_0" : 3 + }, + "indices" : 4, + "material" : 0 + } + ] + } + ], + "nodes" : [ + { + "mesh" : 0, + "name" : "Cube" + } + ], + "scene" : 0, + "scenes" : [ + { + "name" : "Scene", + "nodes" : [ + 0 + ] + } + ] +} diff --git a/and_proj/app/src/main/assets/assets/textures/metalplate01_rgba.ktx b/and_proj/app/src/main/assets/assets/textures/metalplate01_rgba.ktx new file mode 100644 index 0000000..6f3f612 Binary files /dev/null and b/and_proj/app/src/main/assets/assets/textures/metalplate01_rgba.ktx differ diff --git a/and_proj/app/src/main/assets/assets/textures/transparent_glass_rgba.ktx b/and_proj/app/src/main/assets/assets/textures/transparent_glass_rgba.ktx new file mode 100644 index 0000000..1c98f7a Binary files /dev/null and b/and_proj/app/src/main/assets/assets/textures/transparent_glass_rgba.ktx differ diff --git a/and_proj/app/src/main/assets/shaders/README.adoc b/and_proj/app/src/main/assets/shaders/README.adoc new file mode 100644 index 0000000..acdd4b5 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/README.adoc @@ -0,0 +1,34 @@ +//// +- Copyright (c) 2024-2025, Sascha Willems +- +- SPDX-License-Identifier: Apache-2.0 +- +- Licensed under the Apache License, Version 2.0 the "License"; +- you may not use this file except in compliance with the License. +- You may obtain a copy of the License at +- +- http://www.apache.org/licenses/LICENSE-2.0 +- +- Unless required by applicable law or agreed to in writing, software +- distributed under the License is distributed on an "AS IS" BASIS, +- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +- See the License for the specific language governing permissions and +- limitations under the License. +- +//// += Shaders + +== Shader languages + +This folder contains the textual shaders for the samples. All samples come with GLSL shaders and some optionally with HLSL shaders. For samples that support both shader language this is a good way to compare GLSL to HLSL syntax when targeting SPIR-V for Vulkan. + +== Compiling shaders + +The samples load offline compiled SPIR-V variants of the GLSL/HLSL shaders. If you have the appropriate compiler installed, e.g. via the LunarG VUlkan SDK, shaders will be automatically compiled when building the samples project. + +== Further information + +The xref:guide:ROOT:index.adoc[Vulkan Guide] contains further information on how to use HLSL with Vulkan and how it compares to GLSL: + +* xref:guide::hlsl.adoc[HLSL in Vulkan] +* xref:guide::high_level_shader_language_comparison.adoc[High level shading language comparison] \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/base.frag b/and_proj/app/src/main/assets/shaders/base.frag new file mode 100644 index 0000000..d6bc3ca --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/base.frag @@ -0,0 +1,89 @@ +#version 320 es +/* Copyright (c) 2019-2025, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +precision highp float; + +layout(set = 0, binding = 0) uniform sampler2D base_color_texture; + +layout(location = 0) in vec4 in_pos; +layout(location = 1) in vec2 in_uv; +layout(location = 2) in vec3 in_normal; + +layout(location = 0) out vec4 o_color; + +layout(set = 0, binding = 1) uniform GlobalUniform +{ + mat4 model; + mat4 view_proj; + vec3 camera_position; +} +global_uniform; + +// Push constants come with a limitation in the size of data. +// The standard requires at least 128 bytes +layout(push_constant, std430) uniform PBRMaterialUniform +{ + vec4 base_color_factor; + float metallic_factor; + float roughness_factor; +} +pbr_material_uniform; + +#include "lighting.h" + +layout(set = 0, binding = 4) uniform LightsInfo +{ + Light directional_lights[48]; + Light point_lights[48]; + Light spot_lights[48]; +} +lights_info; + +layout(constant_id = 0) const uint DIRECTIONAL_LIGHT_COUNT = 0U; +layout(constant_id = 1) const uint POINT_LIGHT_COUNT = 0U; +layout(constant_id = 2) const uint SPOT_LIGHT_COUNT = 0U; + +void main(void) +{ + vec3 normal = normalize(in_normal); + + vec3 light_contribution = vec3(0.0); + + for (uint i = 0U; i < DIRECTIONAL_LIGHT_COUNT; ++i) + { + light_contribution += apply_directional_light(lights_info.directional_lights[i], normal); + } + + for (uint i = 0U; i < POINT_LIGHT_COUNT; ++i) + { + light_contribution += apply_point_light(lights_info.point_lights[i], in_pos.xyz, normal); + } + + for (uint i = 0U; i < SPOT_LIGHT_COUNT; ++i) + { + light_contribution += apply_spot_light(lights_info.spot_lights[i], in_pos.xyz, normal); + } + + vec4 base_color = vec4(1.0, 0.0, 0.0, 1.0); + + base_color = texture(base_color_texture, in_uv); + + vec3 ambient_color = vec3(0.2) * base_color.xyz; + + o_color = vec4(ambient_color + light_contribution * base_color.xyz, base_color.w); +} diff --git a/and_proj/app/src/main/assets/shaders/base.frag.spv b/and_proj/app/src/main/assets/shaders/base.frag.spv new file mode 100644 index 0000000..3b5b7a3 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/base.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/base.vert b/and_proj/app/src/main/assets/shaders/base.vert new file mode 100644 index 0000000..4a2e51a --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/base.vert @@ -0,0 +1,42 @@ +#version 320 es +/* Copyright (c) 2019, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout(location = 0) in vec3 position; +layout(location = 1) in vec2 texcoord_0; +layout(location = 2) in vec3 normal; + +layout(set = 0, binding = 1) uniform GlobalUniform { + mat4 model; + mat4 view_proj; + vec3 camera_position; +} global_uniform; + +layout (location = 0) out vec4 o_pos; +layout (location = 1) out vec2 o_uv; +layout (location = 2) out vec3 o_normal; + +void main(void) +{ + o_pos = global_uniform.model * vec4(position, 1.0); + + o_uv = texcoord_0; + + o_normal = mat3(global_uniform.model) * normal; + + gl_Position = global_uniform.view_proj * o_pos; +} diff --git a/and_proj/app/src/main/assets/shaders/base.vert.spv b/and_proj/app/src/main/assets/shaders/base.vert.spv new file mode 100644 index 0000000..77397e5 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/base.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/imgui.frag b/and_proj/app/src/main/assets/shaders/imgui.frag new file mode 100644 index 0000000..4c1d8f3 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/imgui.frag @@ -0,0 +1,30 @@ +#version 320 es +/* Copyright (c) 2019, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +precision mediump float; + +layout (binding = 0) uniform sampler2D fontSampler; + +layout (location = 0) in vec2 inUV; +layout (location = 1) in vec4 inColor; + +layout (location = 0) out vec4 outColor; + +void main() +{ + outColor = inColor * texture(fontSampler, inUV); +} diff --git a/and_proj/app/src/main/assets/shaders/imgui.frag.spv b/and_proj/app/src/main/assets/shaders/imgui.frag.spv new file mode 100644 index 0000000..743cb8d Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/imgui.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/imgui.vert b/and_proj/app/src/main/assets/shaders/imgui.vert new file mode 100644 index 0000000..86e3e0c --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/imgui.vert @@ -0,0 +1,42 @@ +#version 320 es +/* Copyright (c) 2019, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +precision mediump float; + +layout (location = 0) in vec2 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 2) in vec4 inColor; + +layout (push_constant) uniform PushConstants { + mat4 transform; +} pushConstants; + +layout (location = 0) out vec2 outUV; +layout (location = 1) out vec4 outColor; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outUV = inUV; + outColor = inColor; + gl_Position = pushConstants.transform * vec4(inPos.xy, 0.0, 1.0); +} diff --git a/and_proj/app/src/main/assets/shaders/imgui.vert.spv b/and_proj/app/src/main/assets/shaders/imgui.vert.spv new file mode 100644 index 0000000..f6d0a23 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/imgui.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/includes/glsl/lighting.h b/and_proj/app/src/main/assets/shaders/includes/glsl/lighting.h new file mode 100644 index 0000000..87b3429 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/includes/glsl/lighting.h @@ -0,0 +1,52 @@ +/* Copyright (c) 2020-2025, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +struct Light +{ + vec4 position; // position.w represents type of light + vec4 color; // color.w represents light intensity + vec4 direction; // direction.w represents range + vec2 info; // (only used for spot lights) info.x represents light inner cone angle, info.y represents light outer cone angle +}; + +vec3 apply_directional_light(Light light, vec3 normal) +{ + vec3 world_to_light = -light.direction.xyz; + world_to_light = normalize(world_to_light); + float ndotl = clamp(dot(normal, world_to_light), 0.0, 1.0); + return ndotl * light.color.w * light.color.rgb; +} + +vec3 apply_point_light(Light light, vec3 pos, vec3 normal) +{ + vec3 world_to_light = light.position.xyz - pos; + float dist = length(world_to_light) * 0.005; + float atten = 1.0 / (dist * dist); + world_to_light = normalize(world_to_light); + float ndotl = clamp(dot(normal, world_to_light), 0.0, 1.0); + return ndotl * light.color.w * atten * light.color.rgb; +} + +vec3 apply_spot_light(Light light, vec3 pos, vec3 normal) +{ + vec3 light_to_pixel = normalize(pos - light.position.xyz); + float theta = dot(light_to_pixel, normalize(light.direction.xyz)); + float inner_cone_angle = light.info.x; + float outer_cone_angle = light.info.y; + float intensity = (theta - outer_cone_angle) / (inner_cone_angle - outer_cone_angle); + return smoothstep(0.0, 1.0, intensity) * light.color.w * light.color.rgb; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag new file mode 100644 index 0000000..42f03b2 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag @@ -0,0 +1,31 @@ +#version 450 +/* Copyright (c) 2022-2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#extension GL_EXT_nonuniform_qualifier : require + +layout (set = 0, binding = 1) uniform sampler2D textures[]; + +layout (location = 0) in vec2 inUV; +layout (location = 1) flat in int inTexIndex; + +layout (location = 0) out vec4 outFragColor; + +void main() +{ + outFragColor = texture(textures[nonuniformEXT(inTexIndex)], inUV); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag.spv b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag.spv new file mode 100644 index 0000000..88231fd Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert new file mode 100644 index 0000000..480f564 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert @@ -0,0 +1,37 @@ +#version 450 +/* Copyright (c) 2022-2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 2) in int inTexIndex; + +layout (binding = 0) uniform UBO +{ + mat4 projection; + mat4 view; +} ubo; + +layout (location = 0) out vec2 outUV; +layout (location = 1) flat out int outTexIndex; + +void main() +{ + outUV = inUV; + outTexIndex = inTexIndex; + gl_Position = ubo.projection * ubo.view * vec4(inPos.xyz, 1.0); +} diff --git a/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert.spv b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert.spv new file mode 100644 index 0000000..20b1735 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/glsl/profiles.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.hlsl b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.hlsl new file mode 100644 index 0000000..15359b2 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.hlsl @@ -0,0 +1,33 @@ +/* Copyright (c) 2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +[[vk::binding(1, 0)]] +Texture2D textures[] : register(t1, space0); +[[vk::binding(1, 0)]] +SamplerState samplers[] : register(s1, space0); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] nointerpolation int TexIndex : TEXCOORD1; +}; + +float4 main(VSOutput input) : SV_TARGET +{ + return textures[NonUniformResourceIndex(input.TexIndex)].Sample(samplers[NonUniformResourceIndex(input.TexIndex)], input.UV); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.spv b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.spv new file mode 100644 index 0000000..bcf4079 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.hlsl b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.hlsl new file mode 100644 index 0000000..bfaf1bb --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.hlsl @@ -0,0 +1,48 @@ +/* Copyright (c) 2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +struct VSInput +{ + [[vk::location(0)]] float3 Pos : POSITION0; + [[vk::location(1)]] float2 UV : TEXCOORD0; + [[vk::location(2)]] int TexIndex : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; +}; +[[vk::binding(0, 0)]] +ConstantBuffer ubo : register(b0, space0); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] nointerpolation int TexIndex : TEXCOORD1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput) 0; + output.UV = input.UV; + output.TexIndex = input.TexIndex; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(input.Pos.xyz, 1.0))); + return output; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.spv b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.spv new file mode 100644 index 0000000..073a031 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/hlsl/profiles.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.slang b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.slang new file mode 100644 index 0000000..a431205 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.slang @@ -0,0 +1,32 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +[[vk::binding(1, 0)]] +Sampler2D textures[] : register(t1, space0); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] nointerpolation int TexIndex : TEXCOORD1; +}; + +[shader("fragment")] +float4 main(VSOutput input) : SV_TARGET +{ + return textures[NonUniformResourceIndex(input.TexIndex)].Sample(input.UV); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.spv b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.spv new file mode 100644 index 0000000..177679d Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.slang b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.slang new file mode 100644 index 0000000..f918105 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.slang @@ -0,0 +1,49 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +struct VSInput +{ + [[vk::location(0)]] float3 Pos : POSITION0; + [[vk::location(1)]] float2 UV : TEXCOORD0; + [[vk::location(2)]] int TexIndex : TEXCOORD1; +}; + +struct UBO +{ + float4x4 projection; + float4x4 view; +}; +[[vk::binding(0, 0)]] +ConstantBuffer ubo : register(b0, space0); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] nointerpolation int TexIndex : TEXCOORD1; +}; + +[shader("vertex")] +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput) 0; + output.UV = input.UV; + output.TexIndex = input.TexIndex; + output.Pos = mul(ubo.projection, mul(ubo.view, float4(input.Pos.xyz, 1.0))); + return output; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.spv b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.spv new file mode 100644 index 0000000..fe7b725 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/profiles/slang/profiles.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag new file mode 100644 index 0000000..ee29b3d --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag @@ -0,0 +1,15 @@ +#version 450 + +// 输入变量(与顶点着色器输出对应) +layout(location = 0) in vec2 inTexCoord; + +// 输出颜色 +layout(location = 0) out vec4 outColor; + +// 纹理采样器 +layout(binding = 0) uniform sampler2D texSampler; + +void main() { + // 采样纹理 + outColor = texture(texSampler, inTexCoord); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag.spv new file mode 100644 index 0000000..705a775 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert new file mode 100644 index 0000000..0769410 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert @@ -0,0 +1,65 @@ +#version 450 + +// 硬编码的顶点数据 - 4个顶点组成三角形带覆盖整个屏幕 +// const vec2 positions[6] = vec2[6]( +// vec2( 1.0, 1.0), // 右上 - 三角形1 +// vec2(-1.0, 1.0), // 左上 - 三角形1 +// vec2(-1.0, -1.0), // 左下 - 三角形1 + +// vec2(-1.0, -1.0), // 左下 - 三角形2 +// vec2( 1.0, -1.0), // 右下 - 三角形2 +// vec2( 1.0, 1.0) // 右上 - 三角形2 +// ); + +const float offset = (640-480)/(480.0); + + +const vec2 positions[6] = vec2[6]( + vec2( 1.0, -1.0 -offset), // 右下 + vec2(1.0, 1.0 + offset), // 右上 - 三角形1 + vec2(-1.0, 1.0 + offset), // 左上 - 三角形1 + + vec2(-1.0, 1.0 + offset), // 左上 - 三角形2 + vec2( -1.0, -1.0-offset), // 左下 - 三角形2 + vec2( 1.0, -1.0-offset) // 右下 - 三角形2 +); + + +//const float offset = (640-480)/(640.0*2); // 假设宽高比为4:3 +// const float offset = 0; + +// const vec2 positions[6] = vec2[6]( +// vec2( -1.0 - offset, 1.0), // 右上 -> 左上 +// vec2(-1.0 - offset, -1.0), // 左上 - 左下 +// vec2(1.0 + offset, -1.0), // 左下 - 右下 + +// vec2(1.0 + offset, -1.0), // 左下 - 右下 +// vec2( 1.0 + offset, 1.0), // 右下 - 右上 +// vec2( -1.0 - offset, 1.0) // 右上 - 左上 +// ); + + + +const vec2 texCoords[6] = vec2[6]( + vec2(1.0, 1.0), // 右上 + vec2(0.0, 1.0), // 左上 + vec2(0.0, 0.0), // 左下 + + vec2(0.0, 0.0), // 左下 + vec2(1.0, 0.0), // 右下 + vec2(1.0, 1.0) // 右上 +); + +// 输出变量 +layout(location = 0) out vec2 outTexCoord; + +void main() { + // 获取顶点位置 + vec2 position = positions[gl_VertexIndex]; + + // 设置输出位置(Vulkan使用不同的坐标系) + gl_Position = vec4(position, 0.0, 1.0); + + // 输出纹理坐标 + outTexCoord = texCoords[gl_VertexIndex]; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert.spv new file mode 100644 index 0000000..1d843ff Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/bg.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag new file mode 100644 index 0000000..1c8908e --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag @@ -0,0 +1,29 @@ +#version 450 + +layout(location = 0) in vec3 fragColor; +layout(location = 1) in vec3 fragLineStart; +layout(location = 2) in vec3 fragLineEnd; + +layout(location = 0) out vec4 outColor; + +void main() { + vec2 fragPos = gl_FragCoord.xy; + + // 网格参数 + float gridSize = 14.0; // 网格大小 + float dotRadius = 6.0; // 点状半径 + + // 计算当前片段所在的网格和网格中心坐标 + vec2 gridCoord = fragPos / gridSize; + vec2 gridCenter = (floor(gridCoord) + 0.5) * gridSize; + + // 计算片段到网格中心的距离 + float distanceToCenter = length(fragPos - gridCenter); + + // 如果距离超过点状半径,丢弃(创建点状虚线) + if (distanceToCenter > dotRadius && fragColor.y > 0.5) { + discard; + } + + outColor = vec4(fragColor, 1.0); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag.spv new file mode 100644 index 0000000..982d99e Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert new file mode 100644 index 0000000..cc00794 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert @@ -0,0 +1,27 @@ +#version 450 + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inColor; +layout(location = 2) in vec3 inLineStart; +layout(location = 3) in vec3 inLineEnd; + +layout(location = 0) out vec3 fragColor; +layout(location = 1) out vec3 fragLineStart; +layout(location = 2) out vec3 fragLineEnd; + + +layout(binding = 0) uniform UniformBufferObject { + mat4 proj; + mat4 model; + mat4 view; +} ubo; + +void main() { + mat4 worldviewproj = ubo.proj * ubo.view * ubo.model; + gl_Position = worldviewproj * vec4(inPosition, 1.0); + + fragColor = inColor; + + fragLineStart = (worldviewproj * vec4(inLineStart, 1.0)).xyz; + fragLineEnd = (worldviewproj * vec4(inLineEnd, 1.0)).xyz; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert.spv new file mode 100644 index 0000000..eb72c72 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag new file mode 100644 index 0000000..b34cd22 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag @@ -0,0 +1,11 @@ +#version 450 + +layout(location = 0) in vec3 fragColor; + + +layout(location = 0) out vec4 outColor; + + +void main() { + outColor = vec4(1, 0, 0, 1.0); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag.spv new file mode 100644 index 0000000..e70baf4 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert new file mode 100644 index 0000000..90a467a --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert @@ -0,0 +1,23 @@ +#version 450 + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inColor; +layout(location = 2) in vec3 inLineStart; +layout(location = 3) in vec3 inLineEnd; + +layout(location = 0) out vec3 fragColor; + +layout(binding = 0) uniform UniformBufferObject { + mat4 proj; + mat4 model; + mat4 view; +} ubo; + +void main() { + //mat4 worldviewproj = ubo.proj * ubo.view * ubo.model; + mat4 mvp = ubo.proj * ubo.view * ubo.model; + //gl_Position = worldviewproj * vec4(inPosition, 1.0); + gl_Position = mvp * vec4(inPosition, 1.0); + + fragColor = inColor; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert.spv new file mode 100644 index 0000000..8cfc36a Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/point_line_solid.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag new file mode 100644 index 0000000..2a5e838 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag @@ -0,0 +1,11 @@ +#version 450 + +// 从顶点着色器接收的颜色 +layout(location = 0) in vec3 fragColor; + +// 输出颜色 +layout(location = 0) out vec4 outColor; + +void main() { + outColor = vec4(fragColor, 1.0); // 使用传入的颜色 +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag.spv new file mode 100644 index 0000000..da37f7e Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert new file mode 100644 index 0000000..97ea1cf --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert @@ -0,0 +1,21 @@ +#version 450 + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inColor; + +layout(location = 0) out vec3 fragColor; + +layout(binding = 0) uniform UniformBufferObject { + mat4 proj; + mat4 model; + mat4 view; +} ubo; + +void main() { + // 预计算MVP矩阵以减少乘法次数 + mat4 mvp = ubo.proj * ubo.view * ubo.model; + //vec3 pos = vec3(2.0, inPosition.y, inPosition.z); + gl_Position = mvp * vec4(inPosition, 1.0); + fragColor = inColor; + gl_PointSize = 2.0; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert.spv new file mode 100644 index 0000000..239970f Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/pointcloud.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag new file mode 100644 index 0000000..ccdb2fd --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag @@ -0,0 +1,41 @@ +#version 450 +/* Copyright (c) 2019-2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout (binding = 1) uniform sampler2D samplerColor; + +layout (location = 0) in vec2 inUV; +layout (location = 1) in float inLodBias; +layout (location = 2) in vec3 inNormal; +layout (location = 3) in vec3 inViewVec; +layout (location = 4) in vec3 inLightVec; + +layout (location = 0) out vec4 outFragColor; + +void main() +{ + vec4 color = texture(samplerColor, inUV, inLodBias); + + vec3 N = normalize(inNormal); + vec3 L = normalize(inLightVec); + vec3 V = normalize(inViewVec); + vec3 R = reflect(-L, N); + vec3 diffuse = max(dot(N, L), 0.0) * vec3(1.0); + float specular = pow(max(dot(R, V), 0.0), 16.0) * color.a; + + outFragColor = vec4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag.spv new file mode 100644 index 0000000..e0bc54e Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert new file mode 100644 index 0000000..a836f8d --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert @@ -0,0 +1,57 @@ +#version 450 +/* Copyright (c) 2019-2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout (location = 0) in vec3 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 2) in vec3 inNormal; + +layout (binding = 0) uniform UBO +{ + mat4 projection; + mat4 model; + vec4 viewPos; + float lodBias; +} ubo; + +layout (location = 0) out vec2 outUV; +layout (location = 1) out float outLodBias; +layout (location = 2) out vec3 outNormal; +layout (location = 3) out vec3 outViewVec; +layout (location = 4) out vec3 outLightVec; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outUV = inUV; + outLodBias = ubo.lodBias; + + vec3 worldPos = vec3(ubo.model * vec4(inPos, 1.0)); + + gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0); + + vec4 pos = ubo.model * vec4(inPos, 1.0); + outNormal = mat3(inverse(transpose(ubo.model))) * inNormal; + vec3 lightPos = vec3(0.0); + vec3 lPos = mat3(ubo.model) * lightPos.xyz; + outLightVec = lPos - pos.xyz; + outViewVec = ubo.viewPos.xyz - pos.xyz; +} diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert.spv new file mode 100644 index 0000000..4938ff8 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/glsl/texture.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.hlsl b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.hlsl new file mode 100644 index 0000000..e0bfc51 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.hlsl @@ -0,0 +1,43 @@ +/* Copyright (c) 2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +[[vk::binding(1, 0)]] +Texture2D textureColor : register(t1); +[[vk::binding(1, 0)]] +SamplerState samplerColor : register(s1); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] float LodBias : FLOAT0; + [[vk::location(2)]] float3 Normal : NORMAL0; + [[vk::location(3)]] float3 ViewVec : VECTOR0; + [[vk::location(4)]] float3 LightVec : VECTOR1; +}; + +float4 main(VSOutput input) : SV_TARGET0 +{ + float4 color = textureColor.SampleBias(samplerColor, input.UV, input.LodBias); + float3 N = normalize(input.Normal); + float3 L = normalize(input.LightVec); + float3 V = normalize(input.ViewVec); + float3 R = reflect(-L, N); + float3 diffuse = max(dot(N, L), 0.0).xxx; + float3 specular = (pow(max(dot(R, V), 0.0), 16.0)).xxx * color.a; + return float4(diffuse * color.rgb + specular, 1.0); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.spv b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.spv new file mode 100644 index 0000000..3b16872 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.hlsl b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.hlsl new file mode 100644 index 0000000..8f098f5 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.hlsl @@ -0,0 +1,60 @@ +/* Copyright (c) 2024, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +struct VSInput +{ + [[vk::location(0)]] float3 Pos : POSITION0; + [[vk::location(1)]] float2 UV : TEXCOORD0; + [[vk::location(2)]] float3 Normal : NORMAL0; +}; + +struct UBO +{ + float4x4 projection; + float4x4 model; + float4 viewPos; + float lodBias; +}; +[[vk::binding(0, 0)]] +ConstantBuffer ubo : register(b0); + +struct VSOutput +{ + float4 Pos : SV_POSITION; + [[vk::location(0)]] float2 UV : TEXCOORD0; + [[vk::location(1)]] float LodBias : FLOAT0; + [[vk::location(2)]] float3 Normal : NORMAL0; + [[vk::location(3)]] float3 ViewVec : VECTOR0; + [[vk::location(4)]] float3 LightVec : VECTOR1; +}; + +VSOutput main(VSInput input) +{ + VSOutput output = (VSOutput) 0; + + float3 vecPos = mul((float3x3) ubo.model, input.Pos.xyz).xyz; + float3 lightPos = mul((float3x3) ubo.model, (1.0).xxx); + + output.UV = input.UV; + output.LodBias = ubo.lodBias; + output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0))); + output.Normal = mul((float3x3) ubo.model, input.Normal); + output.LightVec = lightPos - vecPos; + output.ViewVec = ubo.viewPos.xyz - vecPos; + + return output; +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.spv b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.spv new file mode 100644 index 0000000..660d66a Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/texture_loading/hlsl/texture.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/triangle.frag b/and_proj/app/src/main/assets/shaders/triangle.frag new file mode 100644 index 0000000..e188edf --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/triangle.frag @@ -0,0 +1,28 @@ +#version 320 es +/* Copyright (c) 2019, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +precision mediump float; + +layout(location = 0) in vec3 in_color; + +layout(location = 0) out vec4 out_color; + +void main() +{ + out_color = vec4(in_color, 1.0); +} diff --git a/and_proj/app/src/main/assets/shaders/triangle.frag.spv b/and_proj/app/src/main/assets/shaders/triangle.frag.spv new file mode 100644 index 0000000..ea9d373 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/triangle.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/triangle.vert b/and_proj/app/src/main/assets/shaders/triangle.vert new file mode 100644 index 0000000..2988929 --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/triangle.vert @@ -0,0 +1,40 @@ +#version 320 es +/* Copyright (c) 2019-2023, Arm Limited and Contributors + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +precision mediump float; + +layout(location = 0) out vec3 out_color; + +vec2 triangle_positions[3] = vec2[]( + vec2(0.5, -0.5), + vec2(0.5, 0.5), + vec2(-0.5, 0.5) +); + +vec3 triangle_colors[3] = vec3[]( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +void main() +{ + gl_Position = vec4(triangle_positions[gl_VertexIndex], 0.5, 1.0); + + out_color = triangle_colors[gl_VertexIndex]; +} diff --git a/and_proj/app/src/main/assets/shaders/triangle.vert.spv b/and_proj/app/src/main/assets/shaders/triangle.vert.spv new file mode 100644 index 0000000..47a4a12 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/triangle.vert.spv differ diff --git a/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag new file mode 100644 index 0000000..2d6585b --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag @@ -0,0 +1,29 @@ +#version 450 +/* Copyright (c) 2019, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout (binding = 0) uniform sampler2D fontSampler; + +layout (location = 0) in vec2 inUV; +layout (location = 1) in vec4 inColor; + +layout (location = 0) out vec4 outColor; + +void main() +{ + outColor = inColor * texture(fontSampler, inUV); +} \ No newline at end of file diff --git a/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag.spv b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag.spv new file mode 100644 index 0000000..ecf01e0 Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.frag.spv differ diff --git a/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert new file mode 100644 index 0000000..b78c33e --- /dev/null +++ b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert @@ -0,0 +1,40 @@ +#version 450 +/* Copyright (c) 2019, Sascha Willems + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 the "License"; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +layout (location = 0) in vec2 inPos; +layout (location = 1) in vec2 inUV; +layout (location = 2) in vec4 inColor; + +layout (push_constant) uniform PushConstants { + mat4 transform; +} pushConstants; + +layout (location = 0) out vec2 outUV; +layout (location = 1) out vec4 outColor; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + outUV = inUV; + outColor = inColor; + gl_Position = pushConstants.transform * vec4(inPos.xy, 0.0, 1.0); +} diff --git a/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert.spv b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert.spv new file mode 100644 index 0000000..6eee68e Binary files /dev/null and b/and_proj/app/src/main/assets/shaders/uioverlay/uioverlay.vert.spv differ diff --git a/app/android/java/com/khronos/vulkan_samples/AssetsCopyUtil.java b/app/android/java/com/khronos/vulkan_samples/AssetsCopyUtil.java new file mode 100644 index 0000000..4b0e89e --- /dev/null +++ b/app/android/java/com/khronos/vulkan_samples/AssetsCopyUtil.java @@ -0,0 +1,391 @@ +package com.khronos.vulkan_samples; + +import android.content.Context; +import android.content.res.AssetManager; +import android.os.Environment; +import android.util.Log; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Set; + +public class AssetsCopyUtil { + private static final String TAG = "AssetsCopyUtil"; + private static final String PREF_NAME = "assets_copy_pref"; + private static final String PREF_KEY_COPIED_FILES = "copied_files"; + + /** + * 复制 assets 到应用专属外部存储的 files 目录(递归复制子文件夹) + */ + public static void copyAssetsToAppFiles(Context context, String assetsPath) { + try { + AssetManager assetManager = context.getAssets(); + + // 获取应用专属外部存储的 files 目录 + File externalFilesDir = context.getExternalFilesDir(null); + if (externalFilesDir == null) { + Log.e(TAG, "External files directory is not available"); + return; + } + + // 递归复制 + copyAssetsRecursive(context, assetManager, assetsPath, externalFilesDir.getAbsolutePath()); + + Log.i(TAG, "Assets copy completed for: " + assetsPath); + + } catch (Exception e) { + Log.e(TAG, "Error copying assets from: " + assetsPath, e); + } + } + + /** + * 递归复制 assets 中的文件和文件夹 + */ + private static void copyAssetsRecursive(Context context, AssetManager assetManager, + String assetsPath, String targetBasePath) { + try { + // 获取 assets 路径下的所有项目 + String[] items = assetManager.list(assetsPath); + if (items == null || items.length == 0) { + Log.w(TAG, "No items found in assets path: " + assetsPath); + return; + } + + // 创建目标目录 + File targetDir = new File(targetBasePath, assetsPath); + if (!targetDir.exists() && !targetDir.mkdirs()) { + Log.e(TAG, "Failed to create target directory: " + targetDir.getAbsolutePath()); + return; + } + + // 获取已复制的文件列表 + Set copiedFiles = getCopiedFiles(context); + boolean hasNewFiles = false; + + for (String item : items) { + String assetItemPath = assetsPath.isEmpty() ? item : assetsPath + "/" + item; + String fileKey = assetItemPath; + + // 检查是否已经复制过 + if (copiedFiles.contains(fileKey)) { + Log.d(TAG, "Item already copied: " + assetItemPath); + continue; + } + + try { + // 判断是文件还是目录的正确方法 + boolean isFile = isAssetFile(assetManager, assetsPath, item); + + if (isFile) { + // 复制文件 + if (copySingleFile(assetManager, assetItemPath, targetDir, item)) { + copiedFiles.add(fileKey); + hasNewFiles = true; + Log.d(TAG, "Successfully copied file: " + assetItemPath); + } + } else { + // 递归复制子目录 + copyAssetsRecursive(context, assetManager, assetItemPath, targetBasePath); + // 将目录也标记为已处理 + copiedFiles.add(fileKey); + hasNewFiles = true; + Log.d(TAG, "Processed directory: " + assetItemPath); + } + + } catch (Exception e) { + Log.e(TAG, "Error processing: " + assetItemPath, e); + } + } + + // 如果有新文件被复制,更新记录 + if (hasNewFiles) { + saveCopiedFiles(context, copiedFiles); + } + + } catch (Exception e) { + Log.e(TAG, "Error in recursive copy for path: " + assetsPath, e); + } + } + + /** + * 正确判断 assets 中的项目是文件还是目录 + */ + private static boolean isAssetFile(AssetManager assetManager, String basePath, String item) { + try { + // 方法1:尝试列出子项,如果能列出且不为空,说明是目录 + String testPath = basePath.isEmpty() ? item : basePath + "/" + item; + String[] subItems = assetManager.list(testPath); + + // 如果子项为空,说明是文件或者是空目录 + if (subItems == null) { + return true; // 应该是文件 + } + + // 如果有子项,说明是目录 + if (subItems.length > 0) { + return false; // 是目录 + } + + // 如果子项为空数组,需要进一步判断 + // 尝试打开它,如果能打开说明是文件,不能打开说明是空目录 + try { + InputStream test = assetManager.open(testPath); + test.close(); + return true; // 能打开,是文件 + } catch (Exception e) { + return false; // 不能打开,是空目录 + } + + } catch (Exception e) { + Log.e(TAG, "Error checking asset type: " + item, e); + return true; // 默认当作文件处理 + } + } + + /** + * 更可靠的递归复制方法 + */ + public static void copyAssetsToAppFilesSimple(Context context, String assetsPath) { + try { + AssetManager assetManager = context.getAssets(); + File externalFilesDir = context.getExternalFilesDir(null); + if (externalFilesDir == null) { + Log.e(TAG, "External storage not available"); + return; + } + + // 创建目标目录 + File targetBaseDir = new File(externalFilesDir, assetsPath); + if (!targetBaseDir.exists() && !targetBaseDir.mkdirs()) { + Log.e(TAG, "Failed to create base directory"); + return; + } + + copyAssetsRecursiveSimple(assetManager, assetsPath, targetBaseDir.getAbsolutePath()); + Log.i(TAG, "Simple copy completed for: " + assetsPath); + + } catch (Exception e) { + Log.e(TAG, "Error in simple copy", e); + } + } + + private static void copyAssetsRecursiveSimple(AssetManager assetManager, String assetsPath, String targetPath) { + try { + String[] items = assetManager.list(assetsPath); + if (items == null || items.length == 0) { + return; + } + + for (String item : items) { + String fullAssetPath = assetsPath.isEmpty() ? item : assetsPath + "/" + item; + + // 判断是文件还是目录 + boolean isFile = isAssetFileSimple(assetManager, fullAssetPath); + + if (isFile) { + // 复制文件 + copySingleFileSimple(assetManager, fullAssetPath, targetPath, item); + Log.d(TAG, "Copied file: " + fullAssetPath + " to " + targetPath); + } else { + // 创建子目录并递归复制 + File subDir = new File(targetPath, item); + if (!subDir.exists()) { + subDir.mkdirs(); + } + copyAssetsRecursiveSimple(assetManager, fullAssetPath, subDir.getAbsolutePath()); + Log.d(TAG, "Processed directory: " + fullAssetPath); + } + } + } catch (Exception e) { + Log.e(TAG, "Error in simple recursive copy: " + assetsPath, e); + } + } + + private static boolean isAssetFileSimple(AssetManager assetManager, String path) { + try { + String[] subItems = assetManager.list(path); + if (subItems == null) return true; // 应该是文件 + + if (subItems.length > 0) return false; // 有子项,是目录 + + // 空数组,尝试打开判断 + try { + InputStream test = assetManager.open(path); + test.close(); + return true; // 能打开,是文件 + } catch (Exception e) { + return false; // 不能打开,是空目录 + } + } catch (Exception e) { + return true; // 出错时默认当作文件 + } + } + + /** + * 复制单个文件 + */ + private static boolean copySingleFile(AssetManager assetManager, String assetFilePath, File targetDir, String filename) { + InputStream in = null; + OutputStream out = null; + + try { + File outFile = new File(targetDir, filename); + in = assetManager.open(assetFilePath); + out = new FileOutputStream(outFile); + + byte[] buffer = new byte[1024]; + int read; + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + + Log.d(TAG, "File copied: " + outFile.getAbsolutePath()); + return true; + + } catch (Exception e) { + Log.e(TAG, "Failed to copy file: " + assetFilePath, e); + return false; + } finally { + try { + if (in != null) in.close(); + if (out != null) { + out.flush(); + out.close(); + } + } catch (Exception e) { + Log.e(TAG, "Error closing streams", e); + } + } + } + + private static void copySingleFileSimple(AssetManager assetManager, String assetFilePath, + String targetPath, String filename) { + InputStream in = null; + OutputStream out = null; + + try { + File outFile = new File(targetPath, filename); + in = assetManager.open(assetFilePath); + out = new FileOutputStream(outFile); + + byte[] buffer = new byte[1024]; + int read; + while ((read = in.read(buffer)) != -1) { + out.write(buffer, 0, read); + } + + } catch (Exception e) { + Log.e(TAG, "Error copying: " + assetFilePath, e); + } finally { + try { + if (in != null) in.close(); + if (out != null) { + out.flush(); + out.close(); + } + } catch (Exception e) { + Log.e(TAG, "Error closing streams", e); + } + } + } + + /** + * 调试方法:打印 assets 结构 + */ + public static void printAssetsStructure(Context context, String path) { + try { + Log.d(TAG, "=== Assets Structure for: " + path + " ==="); + AssetManager am = context.getAssets(); + printAssetsRecursive(am, path, 0); + Log.d(TAG, "=== End of Assets Structure ==="); + } catch (Exception e) { + Log.e(TAG, "Error printing assets structure", e); + } + } + + private static void printAssetsRecursive(AssetManager am, String path, int depth) { + try { + String indent = ""; + for (int i = 0; i < depth; i++) indent += " "; + + String[] items = am.list(path); + if (items != null) { + for (String item : items) { + String fullPath = path.isEmpty() ? item : path + "/" + item; + boolean isFile = isAssetFileSimple(am, fullPath); + + if (isFile) { + Log.d(TAG, indent + "📄 " + item + " (file)"); + } else { + Log.d(TAG, indent + "📁 " + item + " (dir)"); + printAssetsRecursive(am, fullPath, depth + 1); + } + } + } + } catch (Exception e) { + Log.e(TAG, "Error in recursive print", e); + } + } + + /** + * 获取已复制的文件列表 + */ + @SuppressWarnings("unchecked") + private static Set getCopiedFiles(Context context) { + return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + .getStringSet(PREF_KEY_COPIED_FILES, new HashSet()); + } + + /** + * 保存已复制的文件列表 + */ + private static void saveCopiedFiles(Context context, Set copiedFiles) { + context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + .edit() + .putStringSet(PREF_KEY_COPIED_FILES, new HashSet<>(copiedFiles)) + .apply(); + } + + /** + * 清空复制记录 + */ + public static void clearCopyRecords(Context context) { + context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE) + .edit() + .remove(PREF_KEY_COPIED_FILES) + .apply(); + Log.d(TAG, "Copy records cleared"); + } + + /** + * 检查外部存储是否可用 + */ + public static boolean isExternalStorageAvailable() { + String state = Environment.getExternalStorageState(); + return Environment.MEDIA_MOUNTED.equals(state); + } + + /** + * 获取目标文件的完整路径 + */ + public static String getFilePath(Context context, String relativePath) { + File externalFilesDir = context.getExternalFilesDir(null); + if (externalFilesDir == null) return null; + + File targetFile = new File(externalFilesDir, relativePath); + return targetFile.getAbsolutePath(); + } + + /** + * 检查文件是否存在 + */ + public static boolean fileExists(Context context, String relativePath) { + File externalFilesDir = context.getExternalFilesDir(null); + if (externalFilesDir == null) return false; + + File targetFile = new File(externalFilesDir, relativePath); + return targetFile.exists(); + } +} \ No newline at end of file