diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index f624d6c8..83710007 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -10,17 +10,18 @@ endmacro() CreateProject(00.triangle main.cpp) CreateProject(01.indices_rect indices_rect.cpp) CreateProject(02.texture_rect texture_rect.cpp TGATexture.cpp) -CreateProject(03.Geometry2D Geometry2D.cpp) -CreateProject(04.Geometry3D Geometry3D.cpp) -CreateProject(05.SceneTree SceneTree.cpp) +CreateProject(03.HQFilterTexture HQFilterTexture.cpp TGATexture.cpp) +CreateProject(04.Geometry2D Geometry2D.cpp) +CreateProject(05.Geometry3D Geometry3D.cpp) +CreateProject(06.SceneTree SceneTree.cpp) -CreateProject(06.LoadModel LoadModel.cpp TGATexture.cpp AssimpLoaderMesh.h AssimpLoaderMesh.cpp ViewModelFramework.h) -target_link_libraries(06.LoadModel assimp) +CreateProject(07.LoadModel LoadModel.cpp TGATexture.cpp AssimpLoaderMesh.h AssimpLoaderMesh.cpp ViewModelFramework.h) +target_link_libraries(07.LoadModel assimp) -CreateProject(07.InlineGeometryScene InlineGeometryScene.cpp) +CreateProject(08.InlineGeometryScene InlineGeometryScene.cpp) -CreateProject(08.Atomsphere Atomsphere.cpp) +CreateProject(09.Atomsphere Atomsphere.cpp) -CreateProject(09.Deferred Deferred.cpp TGATexture.cpp) +CreateProject(10.Deferred Deferred.cpp TGATexture.cpp) -CreateProject(10.TextureFormat TextureFormat.cpp TGATexture.cpp) \ No newline at end of file +CreateProject(11.TextureFormat TextureFormat.cpp TGATexture.cpp) \ No newline at end of file diff --git a/example/Vulkan/Geometry2D.cpp b/example/Vulkan/Geometry2D.cpp index 597d6841..22552300 100644 --- a/example/Vulkan/Geometry2D.cpp +++ b/example/Vulkan/Geometry2D.cpp @@ -48,7 +48,7 @@ private: bool InitMaterial() { material=shader_manage->CreateMaterial(OS_TEXT("res/shader/OnlyPosition.vert.spv"), - OS_TEXT("res/shader/FlatColor.frag.spv")); + OS_TEXT("res/shader/drand48.frag.spv")); if(!material) return(false); @@ -161,7 +161,7 @@ public: return(true); } - void Resize(int w,int h) + void Resize(int w,int h) override { BuildCommandBuffer(&render_list); } diff --git a/example/Vulkan/HQFilterTexture.cpp b/example/Vulkan/HQFilterTexture.cpp new file mode 100644 index 00000000..35863340 --- /dev/null +++ b/example/Vulkan/HQFilterTexture.cpp @@ -0,0 +1,236 @@ +// 3.HQFilterTexture +// 测试高质量纹理过滤函数 + +#include"VulkanAppFramework.h" +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +VK_NAMESPACE_BEGIN +Texture2D *LoadTGATexture(const OSString &filename,Device *device); +VK_NAMESPACE_END + +constexpr uint32_t SCREEN_WIDTH=512; +constexpr uint32_t SCREEN_HEIGHT=512; + +constexpr uint32_t VERTEX_COUNT=4; + +constexpr float vertex_data[VERTEX_COUNT][2]= +{ + {0,0}, + {1,0}, + {0,1}, + {1,1} +}; + +constexpr float tex_coord_data[VERTEX_COUNT][2]= +{ + {0,0}, + {1,0}, + {0,1}, + {1,1} +}; + +constexpr uint32_t INDEX_COUNT=6; + +constexpr uint16 index_data[INDEX_COUNT]= +{ + 0,1,3, + 0,3,2 +}; + +class TestApp:public VulkanApplicationFramework +{ +private: + + struct MPD + { + vulkan::Material * material =nullptr; + vulkan::Pipeline * pipeline =nullptr; + vulkan::DescriptorSets * descriptor_sets =nullptr; + vulkan::Renderable * render_obj =nullptr; + + public: + + ~MPD() + { + delete material; + delete render_obj; + delete descriptor_sets; + delete pipeline; + } + }nearest,linear,nearest_hq,linear_hq; + + vulkan::Texture2D * texture =nullptr; + + vulkan::Sampler * sampler_linear =nullptr; + vulkan::Sampler * sampler_nearest =nullptr; + + vulkan::VertexBuffer * vertex_buffer =nullptr; + vulkan::VertexBuffer * tex_coord_buffer =nullptr; + vulkan::IndexBuffer * index_buffer =nullptr; + + SceneNode render_root; + RenderList render_list; +public: + + ~TestApp() + { + SAFE_CLEAR(index_buffer); + SAFE_CLEAR(tex_coord_buffer); + SAFE_CLEAR(vertex_buffer); + SAFE_CLEAR(sampler_nearest); + SAFE_CLEAR(sampler_linear); + SAFE_CLEAR(texture); + } + +private: + + bool InitVBO() + { + vertex_buffer =device->CreateVBO(FMT_RG32F,VERTEX_COUNT,vertex_data); + if(!vertex_buffer)return(false); + + tex_coord_buffer=device->CreateVBO(FMT_RG32F,VERTEX_COUNT,tex_coord_data); + if(!tex_coord_buffer)return(false); + + index_buffer =device->CreateIBO16(INDEX_COUNT,index_data); + if(!index_buffer)return(false); + + return(true); + } + + vulkan::Sampler *InitSampler(VkFilter filter) + { + VkSamplerCreateInfo sampler_create_info; + + sampler_create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + sampler_create_info.pNext = nullptr; + sampler_create_info.flags = 0; + sampler_create_info.magFilter = filter; + sampler_create_info.minFilter = filter; + sampler_create_info.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + sampler_create_info.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler_create_info.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler_create_info.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler_create_info.mipLodBias = 0.0f; + sampler_create_info.anisotropyEnable = false; + sampler_create_info.maxAnisotropy = 0; + sampler_create_info.compareEnable = false; + sampler_create_info.compareOp = VK_COMPARE_OP_NEVER; + sampler_create_info.minLod = 0.0f; + sampler_create_info.maxLod = 1.0f; + sampler_create_info.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + sampler_create_info.unnormalizedCoordinates = false; + + return device->CreateSampler(&sampler_create_info); + } + + bool InitTexture() + { + texture=vulkan::LoadTGATexture(OS_TEXT("res/image/Gear.tga"),device); + return texture; + } + + bool InitMaterial(struct MPD *mpd,vulkan::Sampler *sampler,const OSString &fragment_shader) + { + mpd->material=shader_manage->CreateMaterial(OS_TEXT("res/shader/Texture2D.vert.spv"), + OS_TEXT("res/shader/")+fragment_shader+OS_TEXT(".frag.spv")); + if(!mpd->material) + return(false); + + mpd->descriptor_sets=mpd->material->CreateDescriptorSets(); + + mpd->descriptor_sets->BindSampler(mpd->material->GetSampler("tex"),texture,sampler); + mpd->descriptor_sets->Update(); + + mpd->render_obj=mpd->material->CreateRenderable(VERTEX_COUNT); + mpd->render_obj->Set("Vertex",vertex_buffer); + mpd->render_obj->Set("TexCoord",tex_coord_buffer); + mpd->render_obj->Set(index_buffer); + + AutoDelete + pipeline_creater=new vulkan::PipelineCreater(device,mpd->material,sc_render_target); + pipeline_creater->CloseCullFace(); + pipeline_creater->Set(PRIM_TRIANGLES); + + mpd->pipeline=pipeline_creater->Create(); + + return mpd->pipeline; + } + + bool Add(struct MPD *mpd,const Matrix4f &offset) + { + RenderableInstance *ri=db->CreateRenderableInstance(mpd->pipeline,mpd->descriptor_sets,mpd->render_obj); + + if(!ri)return(false); + + render_root.Add(ri,offset); + + return(true); + } + + bool InitScene() + { + Add(&nearest, translate(-1,-1,0)); + Add(&linear, translate( 0,-1,0)); + Add(&nearest_hq,translate(-1, 0,0)); + Add(&linear_hq, translate( 0, 0,0)); + + render_root.RefreshMatrix(); + render_root.ExpendToList(&render_list); + BuildCommandBuffer(&render_list); + return(true); + } +public: + + bool Init() + { + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + if(!InitVBO()) + return(false); + + sampler_nearest=InitSampler(VK_FILTER_NEAREST); + sampler_linear=InitSampler(VK_FILTER_LINEAR); + + if(!InitTexture()) + return(false); + + if(!InitMaterial(&nearest, sampler_nearest ,OS_TEXT("FlatTexture")))return(false); + if(!InitMaterial(&linear, sampler_linear ,OS_TEXT("FlatTexture")))return(false); + if(!InitMaterial(&nearest_hq, sampler_nearest ,OS_TEXT("hqfilter")))return(false); + if(!InitMaterial(&linear_hq, sampler_linear ,OS_TEXT("hqfilter")))return(false); + + if(!InitScene()) + return(false); + + return(true); + } + + void Resize(int w,int h) override + { + BuildCommandBuffer(&render_list); + } +};//class TestApp:public VulkanApplicationFramework + +int main(int,char **) +{ +#ifdef _DEBUG + if(!vulkan::CheckStrideBytesByFormat()) + return 0xff; +#endif// + + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/texture_rect.cpp b/example/Vulkan/texture_rect.cpp index 59155dd8..8f090f65 100644 --- a/example/Vulkan/texture_rect.cpp +++ b/example/Vulkan/texture_rect.cpp @@ -117,7 +117,7 @@ private: sampler=device->CreateSampler(&sampler_create_info); - descriptor_sets->BindSampler(material->GetSampler("texture_lena"),texture,sampler); + descriptor_sets->BindSampler(material->GetSampler("tex"),texture,sampler); descriptor_sets->BindUBO(material->GetUBO("world"),ubo_mvp); descriptor_sets->Update(); diff --git a/res/image/Gear.tga b/res/image/Gear.tga new file mode 100644 index 00000000..e56330f4 Binary files /dev/null and b/res/image/Gear.tga differ diff --git a/res/image/Yong.tga b/res/image/Yong.tga new file mode 100644 index 00000000..766e6566 Binary files /dev/null and b/res/image/Yong.tga differ diff --git a/res/image/flat_normal.tga b/res/image/flat_normal.tga new file mode 100644 index 00000000..6cb78490 Binary files /dev/null and b/res/image/flat_normal.tga differ diff --git a/res/shader/FlatTexture.frag b/res/shader/FlatTexture.frag index 3d7830ed..f979a503 100644 --- a/res/shader/FlatTexture.frag +++ b/res/shader/FlatTexture.frag @@ -1,11 +1,11 @@ #version 450 core -layout(binding = 2) uniform sampler2D texture_lena; +layout(binding = 2) uniform sampler2D tex; layout(location = 0) in vec2 FragmentTexCoord; layout(location = 0) out vec4 FragColor; void main() { - FragColor=texture(texture_lena,FragmentTexCoord); + FragColor=texture(tex,FragmentTexCoord); } diff --git a/res/shader/Texture2D.vert b/res/shader/Texture2D.vert new file mode 100644 index 00000000..11a4733d --- /dev/null +++ b/res/shader/Texture2D.vert @@ -0,0 +1,16 @@ +#version 450 core + +layout(location = 0) in vec2 Vertex; +layout(location = 1) in vec2 TexCoord; + +layout(location = 0) out vec2 FragmentTexCoord; + +layout(push_constant) uniform Consts { + mat4 local_to_world; +} pc; + +void main() +{ + gl_Position=vec4(Vertex,0.0,1.0)*pc.local_to_world; + FragmentTexCoord=TexCoord; +} diff --git a/res/shader/drand48.frag b/res/shader/drand48.frag new file mode 100644 index 00000000..cb980eb9 --- /dev/null +++ b/res/shader/drand48.frag @@ -0,0 +1,16 @@ +#version 450 core + +layout(location = 0) out vec4 FragColor; + +/* returns a varying number between 0 and 1 */ +float drand48(vec2 co) +{ + return 2 * fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453) - 1; +} + +void main() +{ + float gray=drand48(gl_FragCoord.xy); + + FragColor=vec4(vec3(gray),1.0); +} diff --git a/res/shader/hqfilter.frag b/res/shader/hqfilter.frag new file mode 100644 index 00000000..bc033721 --- /dev/null +++ b/res/shader/hqfilter.frag @@ -0,0 +1,34 @@ +#version 450 core + +layout(binding = 2) uniform sampler2D tex; + +layout(location = 0) in vec2 FragmentTexCoord; +layout(location = 0) out vec4 FragColor; + +vec4 hqfilter(sampler2D samp, vec2 tc) +{ + // Get the size of the texture we'll be sampling from + vec2 texSize = textureSize(samp, 0); + + // Scale our input texture coordinates up, move to center of texel + vec2 uvScaled = tc * texSize + 0.5; + + // Find integer and fractional parts of texture coordinate + vec2 uvInt = floor(uvScaled); + vec2 uvFrac = fract(uvScaled); + + // Replace fractional part of texture coordinate + uvFrac = smoothstep(0.0, 1.0, uvFrac); + + // Reassemble texture coordinate, remove bias, and + // scale back to 0.0 - 1.0 ranage + vec2 uv = (uvInt + uvFrac - 0.5) / texSize; + + // Regular texture lookup + return texture(samp, uv); +} + +void main() +{ + FragColor=hqfilter(tex,FragmentTexCoord); +} diff --git a/res/shader/shader_compile.sh b/res/shader/shader_compile.sh index 62d9f32f..a51bfae0 100755 --- a/res/shader/shader_compile.sh +++ b/res/shader/shader_compile.sh @@ -23,3 +23,8 @@ glslangValidator -V -o gbuffer_composition.frag.spv gbuffer_composition.frag glslangValidator -V -o gbuffer_debug.vert.spv gbuffer_debug.vert glslangValidator -V -o gbuffer_debug.frag.spv gbuffer_debug.frag + +glslangValidator -V -o drand48.frag.spv drand48.frag + +glslangValidator -V -o Texture2D.vert.spv Texture2D.vert +glslangValidator -V -o hqfilter.frag.spv hqfilter.frag \ No newline at end of file