添加复制的资源
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -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
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
@@ -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]
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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> 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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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> 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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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];
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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); // 使用传入的颜色
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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> 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;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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];
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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);
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -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<String> 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<String> getCopiedFiles(Context context) {
|
||||||
|
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
|
||||||
|
.getStringSet(PREF_KEY_COPIED_FILES, new HashSet<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存已复制的文件列表
|
||||||
|
*/
|
||||||
|
private static void saveCopiedFiles(Context context, Set<String> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user