Compare commits

..

No commits in common. "devel_40_World" and "devel_25_MaterialInstanceArray_in_UBO" have entirely different histories.

1339 changed files with 7363 additions and 203070 deletions

View File

@ -1,8 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

@ -1 +1 @@
Subproject commit 0244bff1b60119806f683b54a137cda2cacc17ac
Subproject commit 9582bfafcc0b2b51dfc18e758a9e57582e580dee

@ -1 +1 @@
Subproject commit 6fbc7078181cefc7e5da590c2d4ccc70507934b7
Subproject commit ca9aece201dd581c0576fe5448162686081261ff

2
CMCore

@ -1 +1 @@
Subproject commit c5b37f98353441520374011020dbe63c17796a4d
Subproject commit 072153aa9135d7de413cc9d63e3019e9853d7045

@ -1 +1 @@
Subproject commit f0ff214289a1265898feecbdbbd2ddf50bff5dca
Subproject commit 5e8b83cce4529e6401de59ec010e2ef68b634150

@ -1 +1 @@
Subproject commit 74e33b497274e51c35a5ee19a274b12dc86deecb
Subproject commit bde86e8016713480cd102693708894ab3b6bfabb

2
CMUtil

@ -1 +1 @@
Subproject commit 48383e5f63928bab43320c406219365850507246
Subproject commit c0990c52ebbc2a19b661a3d6fd64891d05e59305

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.0)
PROJECT(ULRE)
@ -8,35 +8,35 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/CMCMakeModule)
set(ULRE_3RDPTY_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/3rdpty)
include_directories(${ULRE_3RDPTY_ROOT_PATH}/NvTriStrip)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
SET(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/inc)
SET(ULRE_RUNTIME_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include(math)
include(vulkan)
include(use_cm_module)
SET(ULRE CMCore
CMPlatform
CMAssetsManage
CMSceneGraph
CMUtil
ULRE.Work
ULRE.Util
ULRE.ShaderGen
ULRE.SceneGraph
${HGL_MATH_LIB}
${RENDER_LIBRARY}
${Vulkan_LIBRARIES})
use_cm_module(Core)
use_cm_module(Util)
use_cm_module(Platform)
use_cm_module(AssetsManage)
use_cm_module(SceneGraph)
SET(ULRE CMCore
CMPlatform
CMAssetsManage
CMSceneGraph
CMUtil
ULRE.Util
ULRE.ShaderGen
ULRE.SceneGraph
${HGL_GLM_LIB}
${RENDER_LIBRARY}
${Vulkan_LIBRARIES})
include_directories(${ULRE_3RDPTY_ROOT_PATH}/NvTriStrip)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
SET(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/inc)
SET(ULRE_RUNTIME_PATH ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(src)
add_subdirectory(example)

View File

@ -1,33 +1,25 @@
# ULRE
experiment project - Ultra Lightweight Rendering Engine
ULRE is a project of an experimental nature. Used to experiment with various rendering-related techniques And do some examples.
ULRE is a project of experimental nature,Used to experiment with various rendering related techniques,And do some examples.
In the future, its complicated version will be integrated into CMGameEngine.Used to replace the old rendering engine.
In the future, its compilicated version will be integrated into CMGameEngine.Used to replace the old rendering engine.
Platform: Windows, Linux (WIP: Android, macOS, iOS)
Platform: Windows,Linux (WIP: Android,macOS,iOS)
Graphics API: Vulkan
Milestone:
2. Texture2DArray was integrated into material instances.
Multiple render instances of the same model use different material instances and textures but are still merged into one render.
Although the changes this time are small, they are more significant.
1. a test was completed, and the entire scene was drawn with only one DrawCall.
Although it still has a lot of unfinished work, it is still a significant milestone.
On May 6 of 2023, a test was completed, and the entire scene was drawn with only one DrawCall. Although it still has a lot of unfinished work, it is still a very important milestone.
#
ULRE是一个试验性质的工程用于试验各种渲染相关的技术以及做一些范例。在未来它的复杂化版本会被整合到CMGameEngine中用于替代旧的渲染引擎。
平台: Windows, Linux (开发中: Android, macOS, iOS)
平台: Windows,Linux (开发中: Android,macOS,iOS)
图形API: Vulkan
里程碑:
2. Texture2DArray集成在材质实例中。同一个模型的多个渲染实例使用不同的材质实例以及不同的纹理
但它们依然被合并成一次渲染。这次的改变虽小,但意义更为重大。
1. 完成了一个测试只用了一次DrawCall就绘制出了整个场景。虽然它还有很多未完成的工作但它依然是一个非常重要的里程碑。
2023年5月6日完成了一个测试只用了一次DrawCall就绘制出了整个场景。虽然它还有很多未完成的工作但它依然是一个非常重要的里程碑。

View File

@ -1,11 +0,0 @@
mat4 GetJointMatrix()
{
// Joint数据分Joint ID和Joint Weight两部分
// Joint ID是一个uvec4在shader中为整数。在C++端可使用RGBA8UI或是RGBA16UI来传递。
// Joint Weight是权重在shader中为浮点。在C++端使用RGBA8或RGBA4来传递。
return joint.mats[JointID.x]*JointWeight.x+
joint.mats[JointID.y]*JointWeight.y+
joint.mats[JointID.z]*JointWeight.z+
joint.mats[JointID.w]*JointWeight.w;
}

View File

@ -1,9 +0,0 @@
mat3 GetNormalMatrix()
{
return mat3(camera.view*GetLocalToWorld());
}
vec3 GetNormal(mat3 normal_matrix,vec3 normal)
{
return normalize(normal_matrix*normal);
}

View File

@ -1,38 +0,0 @@
#Material
Name PureColor2D
Base Std2D
#MaterialInstance
Length 16
Stage Fragment
Code
{
vec4 Color;
}
#Vertex
Code
{
void main()
{
HandoverMI();
gl_Position=GetPosition2D();
}
}
#Fragment
Output
{
vec4 FragColor
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
FragColor=mi.Color;
}
}

View File

@ -1,39 +0,0 @@
#Material
Name PureTexture2D
Base Std2D
#VertexInput
vec2 TexCoord
#Vertex
Output
{
vec2 TexCoord
}
Code
{
void main()
{
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
}
}
#Fragment
sampler2D TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
void main()
{
FragColor=texture(TextureBaseColor,Input.TexCoord);
}
}

View File

@ -1,68 +0,0 @@
#Material
Name RectTexture2D
Base Std2D
Prim SolidRectangles,WireRectangles
#VertexInput
vec4 TexCoord
#Vertex
Output
{
vec4 TexCoord
}
Code
{
void main()
{
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
}
}
#Geometry
in points
out triangle_strip,4
Output
{
vec2 TexCoord
}
Code
{
void main()
{
vec2 vlt=gl_in[0].gl_Position.xy;
vec2 vrb=gl_in[0].gl_Position.zw;
vec2 tlt=Input[0].TexCoord.xy;
vec2 trb=Input[0].TexCoord.zw;
gl_Position=vec4(vlt, vec2(0,1));Output.TexCoord=tlt; EmitVertex();
gl_Position=vec4(vlt.x, vrb.y, vec2(0,1));Output.TexCoord=vec2(tlt.x,trb.y); EmitVertex();
gl_Position=vec4(vrb.x, vlt.y, vec2(0,1));Output.TexCoord=vec2(trb.x,tlt.y); EmitVertex();
gl_Position=vec4(vrb, vec2(0,1));Output.TexCoord=trb; EmitVertex();
EndPrimitive();
}
}
#Fragment
sampler2D TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
void main()
{
FragColor=texture(TextureBaseColor,Input.TexCoord);
}
}

View File

@ -1,79 +0,0 @@
#Material
Name RectTexture2DArray
Base Std2D
Prim SolidRectangles,WireRectangles
#MaterialInstance
Length 16
Stage Fragment
Code
{
uvec4 id;
}
#VertexInput
vec4 TexCoord
#Vertex
Output
{
vec4 TexCoord
}
Code
{
void main()
{
HandoverMI();
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
}
}
#Geometry
in points
out triangle_strip,4
Output
{
vec2 TexCoord
}
Code
{
void main()
{
vec2 vlt=gl_in[0].gl_Position.xy;
vec2 vrb=gl_in[0].gl_Position.zw;
vec2 tlt=Input[0].TexCoord.xy;
vec2 trb=Input[0].TexCoord.zw;
HandoverMI();gl_Position=vec4(vlt, vec2(0,1));Output.TexCoord=tlt; EmitVertex();
HandoverMI();gl_Position=vec4(vlt.x, vrb.y, vec2(0,1));Output.TexCoord=vec2(tlt.x,trb.y); EmitVertex();
HandoverMI();gl_Position=vec4(vrb.x, vlt.y, vec2(0,1));Output.TexCoord=vec2(trb.x,tlt.y); EmitVertex();
HandoverMI();gl_Position=vec4(vrb, vec2(0,1));Output.TexCoord=trb; EmitVertex();
EndPrimitive();
}
}
#Fragment
sampler2DArray TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
FragColor=texture(TextureBaseColor,vec3(Input.TexCoord,mi.id.x));
}
}

View File

@ -1,37 +0,0 @@
#Material
Name VertexColor2D
Base Std2D
#VertexInput
vec4 Color
#Vertex
Output
{
vec4 Color
}
Code
{
void main()
{
Output.Color=Color;
gl_Position=GetPosition2D();
}
}
#Fragment
Output
{
vec4 FragColor
}
Code
{
void main()
{
FragColor=Input.Color;
}
}

View File

@ -1,82 +0,0 @@
#Material
Name BillboardFixedSize
Base Std3D/Billboard
#VertexInput
vec2 TexCoord
#MaterialInstance
Length 8
Stage Vertex
Code
{
uvec2 BillboardSize;
}
#Vertex
Output
{
vec2 BillboardSize
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
Output.BillboardSize=mi.BillboardSize/viewport.canvas_resolution;
gl_Position=GetPosition3D();
gl_Position/=gl_Position.w;
}
}
#Geometry
Output
{
vec2 TexCoord
}
Code
{
void main()
{
const vec2 BillboardVertex[4]=vec2[]
(
vec2(-0.5,-0.5),
vec2(-0.5, 0.5),
vec2( 0.5,-0.5),
vec2( 0.5, 0.5)
);
for(int i=0;i<4;i++)
{
gl_Position=gl_in[0].gl_Position;
gl_Position.xy+=BillboardVertex[i]*Input[0].BillboardSize;
Output.TexCoord=BillboardVertex[i]+vec2(0.5);
EmitVertex();
}
EndPrimitive();
}
}
#Fragment
sampler2D TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
void main()
{
FragColor=texture(TextureBaseColor,Input.TexCoord);
}
}

View File

@ -1,2 +0,0 @@
vec4 direction;
vec4 color;

View File

@ -1,92 +0,0 @@
#Material
Name BlinnPhong+HalfLambert shading model only color
Reference https://zhuanlan.zhihu.com/p/442023993
Base Std3D/BlinnPhong
//某些Require并不真的存在.ubo文件写成一行一个是为了方便未来改成带路径的
Require LocalToWorld
Require Camera
define HAVE_SPECULAR off //默认不定义HAVE_SPECULAR
UBO
{
File BlinnPhongSun.ubo //文件名,如果/开头表示从ShaderLibrary根目录开始没有则表示同一目录
Struct BlinnPhongSun //结构名称
Name sun //在代码中的变量名
Stage Fragment //会引用的shader
Set Global //Descriptor Set
}
#MaterialInstance
Length 16
Stage Fragment
Code
{
vec3 Color;
float Gloss;
}
#VertexInput
vec3 Normal
#Vertex
Output
{
vec4 Position;
vec3 Normal;
}
Code
{
void main()
{
Output.Normal =GetNormal();
Output.Position =GetPosition3D();
HandoverMI();
gl_Position =Output.Position;
}
}
#Fragment
Output
{
vec4 FragColor;
}
Code
{
#define HAVE_SPECULAR
void main()
{
MaterialInstance mi=GetMI();
//点乘法线和光照
float intensity=0.5*max(dot(Input.Normal,sun.direction.xyz),0.0)+0.5;
//直接光颜色
vec3 direct_color =intensity*sun.color.rgb*mi.Color.rgb;
#ifndef HAVE_SPECULAR
FragColor=vec4(direct_color,1.0);
#else
vec3 spec_color=vec3(0.0);
if(intensity>0.0)
{
vec3 half_vector=normalize(sun.direction.xyz+normalize(Input.Position.xyz+camera.pos));
float specular=max(dot(half_vector,Input.Normal),0.0);
spec_color=specular*pow(specular,mi.Gloss)*sun.color.rgb;
}
FragColor=vec4(direct_color+spec_color,1.0);
#endif//HAVE_SPECULAR
}
}

View File

@ -1,100 +0,0 @@
#Material
Name BlinnPhong+HalfLambert shading model only color
Reference https://zhuanlan.zhihu.com/p/442023993
Base Std3D/BlinnPhong
//某些Require并不真的存在.ubo文件写成一行一个是为了方便未来改成带路径的
Require LocalToWorld
Require Camera
define HAVE_SPECULAR off //默认不定义HAVE_SPECULAR
UBO
{
File BlinnPhongSun.ubo //文件名,如果/开头表示从ShaderLibrary根目录开始没有则表示同一目录
Struct BlinnPhongSun //结构名称
Name sun //在代码中的变量名
Stage Fragment //会引用的shader
Set Global //Descriptor Set
}
#MaterialInstance
Length 32
Stage Fragment
Code
{
vec4 Color;
uint tex_id;
}
#VertexInput
vec3 Normal
vec2 TexCoord
#Vertex
Output
{
vec4 Position;
vec3 Normal;
vec2 TexCoord
}
Code
{
void main()
{
Output.Normal =GetNormal();
Output.Position =GetPosition3D();
Output.TexCoord =TexCoord;
HandoverMI();
gl_Position =Output.Position;
}
}
#Fragment
sampler2DArray TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
#define HAVE_SPECULAR
void main()
{
MaterialInstance mi=GetMI();
vec4 texture_color=texture(TextureBaseColor,vec3(Input.TexCoord,mi.tex_id));
//点乘法线和光照
float intensity=0.5*max(dot(Input.Normal,sun.direction.xyz),0.0)+0.5;
//直接光颜色
vec3 direct_color =intensity*sun.color.rgb*mi.Color.rgb*texture_color.rgb;
#ifndef HAVE_SPECULAR
FragColor=vec4(direct_color,1.0);
#else
vec3 spec_color=vec3(0.0);
if(intensity>0.0)
{
vec3 half_vector=normalize(sun.direction.xyz+normalize(Input.Position.xyz+camera.pos));
float specular=max(dot(half_vector,Input.Normal),0.0);
spec_color=specular*pow(specular,8)*sun.color.rgb;
}
FragColor=vec4(direct_color+spec_color,1.0);
#endif//HAVE_SPECULAR
}
}

View File

@ -1,87 +0,0 @@
#Material
Name MetricCellsGrid
Base Std3D
Reference https://www.shadertoy.com/view/wdSXzm
#VertexInput
vec2 TexCoord
#MaterialInstance
Length 120
Stage Fragment
Code
{
vec4 x_color;
vec4 y_color;
vec4 x_axis_color;
vec4 y_axis_color;
vec4 center_color;
vec2 lum; //x=0.1 sub cell line,y=0.2 big cell line
vec2 cell_step;
vec2 big_cell_step;
vec2 scale;
float axis_line_width;
float center_radius;
}
#Vertex
Output
{
vec2 TexCoord
}
Code
{
void main()
{
HandoverMI();
Output.TexCoord=TexCoord;
gl_Position=GetPosition3D();
}
}
#Fragment
Output
{
vec4 FragColor;
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
float edge=viewport.inv_viewport_resolution.y;
float x=(Input.TexCoord.x-0.5)*mi.scale.x;
float y=(Input.TexCoord.y-0.5)*mi.scale.y;
vec4 color=vec4(0,0,0,1);
// ======= Lines + Bold lines
color.xyz += step(1.0 - 1.0 / mi.cell_step.x, fract(x / mi.cell_step.x )) * mi.x_color.rgb * mi.lum.x;
color.xyz += step(1.0 - 1.0 / mi.big_cell_step.x, fract(x / mi.big_cell_step.x)) * mi.x_color.rgb * mi.lum.y;
color.xyz += step(1.0 - 1.0 / mi.cell_step.y, fract(y / mi.cell_step.y )) * mi.y_color.rgb * mi.lum.x;
color.xyz += step(1.0 - 1.0 / mi.big_cell_step.y, fract(y / mi.big_cell_step.y)) * mi.y_color.rgb * mi.lum.y;
// ======= AXES
float xb = step(abs(x) - mi.axis_line_width, 0.0);
float yb = step(abs(y) - mi.axis_line_width, 0.0);
color.rgb = mix(color.rgb, mi.x_axis_color.rgb, (xb));
color.rgb = mix(color.rgb, mi.y_axis_color.rgb, (yb));
// ======= CENTER
float cb = length(vec2(x,y))-mi.center_radius;
color.rgb = mix(color.rgb, mi.center_color.rgb, cb>0.0?0.0:smoothstep(0,edge*mi.scale.y,abs(cb)));
FragColor=color;
}
}

View File

@ -1,38 +0,0 @@
#Material
Name PureColor3D
Base Std3D
#MaterialInstance
Length 16
Stage Fragment
Code
{
vec4 Color;
}
#Vertex
Code
{
void main()
{
HandoverMI();
gl_Position=GetPosition3D();
}
}
#Fragment
Output
{
vec4 FragColor;
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
FragColor=mi.Color;
}
}

View File

@ -1,38 +0,0 @@
#Material
Name VertexColor3D
Base Std3D
#VertexInput
vec4 Color
#Vertex
Output
{
vec4 Color
}
Code
{
void main()
{
Output.Color=Color;
gl_Position=GetPosition3D();
}
}
#Fragment
Output
{
vec4 FragColor;
}
Code
{
void main()
{
FragColor=Input.Color;
}
}

View File

@ -1,47 +0,0 @@
#Material
Name VertexLum3D
Base Std3D
#MaterialInstance
Length 16
Stage Vertex
Code
{
vec4 Color;
}
#VertexInput
float Luminance
#Vertex
Output
{
vec4 Color
}
Code
{
void main()
{
MaterialInstance mi=GetMI();
Output.Color=Luminance*mi.Color;
gl_Position=GetPosition3D();
}
}
#Fragment
Output
{
vec4 FragColor;
}
Code
{
void main()
{
FragColor=Input.Color;
}
}

View File

@ -1,34 +0,0 @@
# 为什么我们使用INI/TOML做为资产文件格式?
大部分的数据文件,我们会将其分为属性文本部分与二进制数据部分。
其中属性部分我们会使用INI/TOML方式编写。这样利于git/hg/svn等版本控制系统进行差异合并。
比如一个纹理贴图它的二进制部分首先是有它的“原始位图数据阵列”它的属性部分包含“宽、高、象素格式”这样的不可更改数据也包括“sRGB/Linear色彩空间、纹理分组、建议过滤方式、特定平台建议的压缩算法”等可调整数据。还有资产使用过程中产生的“引用资产列表”和“被引用资产列表”。
而这些可调整数据,我们可能是会随时修改的,甚至是不同的人可能会修改不同的部分。
如果我们将这些数据全部放入一个二进制文件中比如png/jpeg中。那么每修改一个小小的属性都需要向git/svn仓库提交整个二进制文件。这是相当愚蠢和不合理的。
而众所周知不管是免费的git/hg/svn还是收费的p4它们针对文本文件都会有一系列的差异化比较合并功能。而这个差异化自动合并都是基于文本行的。
所以,我们的所有资产文件,都会分裂成二进制数据文件和属性文本文件。而在这个属性文本文件中,对于每一项属性,是使用独立的行来保存数据的。
# Why do we use the INI/TOML as an asset file format?
For most files, we will split into the attributes text part and binary data part.
We will use the INI/TOML format to write the properties part. Because the format easily merges diff by git/hg/svn.
For example a texture. It's binary data includes "Raw bitmap data".
Its attributes part include "width, height, pixel format", they can't change.
Also, "sRGB/Linear colour space", "texture group", "recommend filter type" and "recommend compress format of special platform".
We may modify this data at any time. Even many people modify different parts at the same time.
If we use a binary file that it includes all data. for example, .png or .jpeg.
We need commit whole binary data after changed a few attributes. This behaviour is quite stupid and irrational.
Most people know this knowledge: Free git/hg/svn and commercial p4. They both include a merge-diff tool, which is text based.
so, we all asset files, they should split into the attributes text part and binary data part.
In this attribute's text file, a separate line is used to save data for each attribute.

View File

@ -1,28 +0,0 @@
# AssetPath
具体源代码参见CMAssetManage中的AssetPath.h
# 大致规则
Asset代表的资产意味应用程序本身所拥有的资源。而AssetPath意味指向这个资产的一个字符串。
AssetPath的组成规和Windows/UNIX/Linux的路径原则类似大致如下
```C++
LOCATION:/abc/123/test_material.mtl
```
LOCATION 它代表资产所在的大范围位置,是可以不存在的,也就是说如下的写法也是可以的
```C++
:/abc/123/test_material.mtl
```
这个LOCATION的定义我们暂时有以下几个
| LOCATION | 意义 |
|----------|------------------|
| 不写 | 应用程序本身的资产包 |
| Asset | 应用程序本身的资产包 |
| Engine | 代表引擎资产 |
| PlugIn | 代表插件资产 |
| ExtPack | 应用程序扩展资产包(一般用于额外安装或下载的资产包) |
| OS | 操作系统真实路径访问 |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

View File

@ -1,47 +0,0 @@
# CreateMaterialInstance
## 1st
最早最根本的方法直接在C++代码层面通过mtl::CreateVertexColor2D()函数来创建MaterialCreateInfo
```C++
mtl::Material2DCreateConfig cfg(GetDeviceAttribute(),"VertexColor2D",PrimitiveType::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
material_instance=CreateMaterialInstance(mci);
```
## 2nd
注册材质系统引入后的方法,通过名称"VertexColor2D"来创建MaterialCreateInfo
```C++
mtl::Material2DCreateConfig cfg(GetDeviceAttribute(),"VertexColor2D",PrimitiveType::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateMaterialCreateInfo("VertexColor2D",&cfg);
material_instance=CreateMaterialInstance(mci);
```
## 3rd
其实是第二种方法在WorkObject层面的封装
```C++
mtl::Material2DCreateConfig cfg(GetDeviceAttribute(),"VertexColor2D",PrimitiveType::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
material_instance=CreateMaterialInstance("VertexColor2D",&cfg);
```
## 4th
是更进一步的封装通过材质配置文件连带Material2DCreateConfig的具体配置都进行了封闭。
```C++
AssetPath path(":/asset/test_material.mtl");
material_instance=CreateMaterialInstance(path);
```

Binary file not shown.

View File

@ -1,20 +0,0 @@
# 程序内嵌材质/Shader
# Material/Shader embedded in program code
问题(Question):
```
即然可以从文件中加载材质了,那为什么还需要有程序代码中内嵌的材质/Shader呢
I can load a material from a file. Why do we need a few materials/shaders embedded in the code?
```
这个问题很好,答案也很简单:
Good question, the answer is straightforward:
```
我们需要在资产损坏或丢失的情况下,依然可以渲染一些内容, 比如: 一个报错对话框。
We need to be able to render some content, such as an error dialog box, even if the asset is damaged or lost.
```

View File

@ -10,6 +10,4 @@
endmacro()
CreateProject(00.line line.cpp)
CreateProject(01.LerpLine LerpLine.cpp)
CreateProject(02.roundbox roundbox.cpp)
CreateProject(01.roundbox roundbox.cpp)

View File

@ -1,121 +0,0 @@
// 主要用于测试几种2D插值算法
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/math/HalfFloat.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT*2]=
{
-1.0, 0.0,
1.0, 0.0,
};
constexpr VkFormat PositionFormat=VF_V2F;
constexpr float color_data[VERTEX_COUNT*4]=
{ 1,0,0,1,
0,1,0,1,
0,0,1,1
};
constexpr VkFormat ColorFormat=VF_V4F;
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitAutoMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"VertexColor2D",PrimitiveType::Lines);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
material_instance=db->CreateMaterialInstance(mci);
return material_instance;
}
bool InitPipeline()
{
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,PrimitiveType::Lines);
return pipeline;
}
bool InitVBO()
{
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Triangle",VERTEX_COUNT);
if(!rpc.WriteVAB(VAN::Position, PositionFormat, position_data))return(false);
if(!rpc.WriteVAB(VAN::Color, ColorFormat, color_data ))return(false);
render_obj=db->CreateMesh(&rpc,material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitAutoMaterial())
return(false);
if(!InitPipeline())
return(false);
if(!InitVBO())
return(false);
if(!BuildCommandBuffer(render_obj))
return(false);
return(true);
}
void Resize(uint w,uint h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -36,7 +36,7 @@ private:
Camera cam;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
DeviceBuffer * ubo_camera_info =nullptr;
DeviceBuffer * ubo_color_material =nullptr;
DeviceBuffer * ubo_line_config =nullptr;
@ -53,8 +53,8 @@ private:
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
//pipeline=CreatePipeline(material_instance,OS_TEXT("res/pipeline/alpha2d"),PrimitiveType::LineStrip); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,InlinePipeline::Alpha2D,PrimitiveType::LineStrip); //等同上一行为Framework重载默认使用swapchain的render target
//pipeline=CreatePipeline(material_instance,OS_TEXT("res/pipeline/alpha2d"),Prim::LineStrip); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,InlinePipeline::Alpha2D,Prim::LineStrip); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -116,9 +116,9 @@ private:
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVAB(VF_V2F,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false);
render_obj=db->CreateMesh(primitive,material_instance,pipeline);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
@ -143,7 +143,7 @@ public:
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
cam.width=w;
cam.height=h;

View File

@ -42,7 +42,7 @@ private:
Camera cam;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
DeviceBuffer * ubo_camera_info =nullptr;
DeviceBuffer * ubo_rb_config =nullptr;
@ -66,7 +66,7 @@ private:
if(!material_instance)
return(false);
pipeline=CreatePipeline(material_instance,OS_TEXT("res/pipeline/alpha2d"),PrimitiveType::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,OS_TEXT("res/pipeline/alpha2d"),Prim::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -138,9 +138,9 @@ private:
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVAB(VF_V4I16,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V4I16,VERTEX_COUNT,position_data)))return(false);
render_obj=db->CreateMesh(primitive,material_instance,pipeline);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
@ -165,7 +165,7 @@ public:
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
cam.width=w;
cam.height=h;

View File

@ -1,199 +0,0 @@
// Billboard
#include<hgl/WorkManager.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/Ray.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VertexDataManager.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/module/TextureManager.h>
#include<hgl/graph/FirstPersonCameraControl.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
static float position_data[3]=
{
0,0,0
};
static float lumiance_data[2]={1,1};
static Color4f white_color(1,1,1,1);
static Color4f yellow_color(1,1,0,1);
class TestApp:public WorkObject
{
Color4f color;
private:
Material * mtl_plane_grid =nullptr;
MaterialInstance * mi_plane_grid =nullptr;
Pipeline * pipeline_plane_grid =nullptr;
Primitive * prim_plane_grid =nullptr;
MaterialInstance * mi_billboard =nullptr;
Pipeline * pipeline_billboard =nullptr;
Mesh * ro_billboard =nullptr;
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
private:
bool InitPlaneGridMP()
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Lines);
cfg.local_to_world=true;
{
cfg.position_format=VAT_VEC2;
mtl_plane_grid=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_plane_grid)return(false);
VILConfig vil_config;
vil_config.Add(VAN::Luminance,VF_V1UN8);
mi_plane_grid=db->CreateMaterialInstance(mtl_plane_grid,&vil_config,&white_color);
if(!mi_plane_grid)return(false);
pipeline_plane_grid=CreatePipeline(mi_plane_grid,InlinePipeline::Solid3D);
if(!pipeline_plane_grid)return(false);
}
return(true);
}
bool InitBillboardMP()
{
mtl::BillboardMaterialCreateConfig cfg(PrimitiveType::Billboard);
{
cfg.fixed_size=true;
mi_billboard=CreateMaterialInstance(mtl::inline_material::Billboard2D,&cfg);
if(!mi_billboard)return(false);
pipeline_billboard=CreatePipeline(mi_billboard,InlinePipeline::Solid3D);
if(!pipeline_billboard)return(false);
}
return(true);
}
bool InitTexture()
{
TextureManager *tex_manager=GetTextureManager();
texture=tex_manager->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"),true);
if(!texture)return(false);
sampler=db->CreateSampler();
if(!mi_billboard->GetMaterial()->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
Vector2u texture_size(texture->GetWidth(),texture->GetHeight());
mi_billboard->WriteMIData(texture_size);
return(true);
}
bool CreateRenderObject()
{
using namespace inline_geometry;
{
auto pc=GetPrimitiveCreater(mi_plane_grid);
struct PlaneGridCreateInfo pgci;
pgci.grid_size.Set(500,500);
pgci.sub_count.Set(5,5);
pgci.lum=128;
pgci.sub_lum=192;
prim_plane_grid=CreatePlaneGrid2D(pc,&pgci);
}
{
auto pc=GetPrimitiveCreater(mi_billboard);
pc->Init("Billboard",1);
if(!pc->WriteVAB(VAN::Position,VF_V3F,position_data))
return(false);
ro_billboard=db->CreateMesh(pc,mi_billboard,pipeline_billboard);
if(!ro_billboard)
return(false);
}
return(true);
}
bool InitScene()
{
SceneNode *scene_root=GetSceneRoot(); //取得缺省场景根节点
CreateComponent<MeshComponent>(scene_root,db->CreateMesh(prim_plane_grid,mi_plane_grid,pipeline_plane_grid));
CreateComponent<MeshComponent>(scene_root,ro_billboard);
CameraControl *camera_control=GetCameraControl();
camera_control->SetPosition(Vector3f(32,32,32));
camera_control->SetTarget(Vector3f(0,0,0));
return(true);
}
public:
using WorkObject::WorkObject;
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
}
bool Init() override
{
if(!InitPlaneGridMP())
return(false);
if(!InitBillboardMP())
return(false);
if(!InitTexture())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("Billboard"),1280,720);
}

View File

@ -1,18 +0,0 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Basic")
endmacro()
CreateProject(01_draw_triangle draw_triangle_use_UBO.cpp)
CreateProject(02_auto_instance auto_instance.cpp)
CreateProject(03_auto_merge_material_instance auto_merge_material_instance.cpp)
CreateProject(04_Billboard BillboardTest.cpp)

View File

@ -1,6 +0,0 @@
#include<hgl/graph/mtl/MaterialLibrary.h>
STD_MTL_NAMESPACE_BEGIN
STD_MTL_NAMESPACE_END

View File

@ -1,113 +0,0 @@
// 该范例主要演示使用RenderList系统绘制多个三角形并利用RenderList进行排序以及自动合并进行Instance渲染
#include<hgl/WorkManager.h>
#include<hgl/math/Math.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t VERTEX_COUNT=3;
constexpr uint32_t TRIANGLE_NUMBER=12;
constexpr float position_data[VERTEX_COUNT*2]=
{
0.0, 0.0,
-0.1, 0.9,
0.1, 0.9
};
constexpr uint8 color_data[VERTEX_COUNT][4]=
{
{255,0,0,255},
{0,255,0,255},
{0,0,255,255}
};
class TestApp:public WorkObject
{
private:
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,
CoordinateSystem2D::NDC,
mtl::WithLocalToWorld::With);
VILConfig vil_config;
vil_config.Add(VAN::Color,VF_V4UN8);
material_instance=CreateMaterialInstance(mtl::inline_material::VertexColor2D,&cfg,&vil_config);
}
if(!material_instance)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
render_obj=CreateMesh("Triangle",VERTEX_COUNT,material_instance,pipeline,
{
{VAN::Position, VF_V2F, position_data},
{VAN::Color, VF_V4UN8, color_data }
});
if(!render_obj)
return(false);
double rad;
Matrix4f mat;
SceneNode *scene_root=GetSceneRoot(); ///<取得场景根节点
for(uint i=0;i<TRIANGLE_NUMBER;i++)
{
rad=deg2rad<double>((360.0f/double(TRIANGLE_NUMBER))*i); //这里一定要加<double>或<float>否则结果用int保存会出现问题
mat=rotate(rad,Vector3f(0,0,1));
CreateComponent<MeshComponent>(mat,scene_root,render_obj);
}
return(true);
}
public:
using WorkObject::WorkObject;
bool Init() override
{
GetRenderer()->SetClearColor(Color4f(0.2f,0.2f,0.2f,1.0f));
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("AutoInstance"),1024,1024);
}

View File

@ -1,122 +0,0 @@
// 该范例主要演示使用一个材质下的不同材质实例传递颜色参数绘制三角形并依赖RenderList中的自动合并功能让同一材质下所有不同材质实例的对象一次渲染完成。
#include<hgl/WorkManager.h>
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/color/Color.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT*2]=
{
0.0, 0.0,
-0.1, 0.9,
0.1, 0.9
};
constexpr uint DRAW_OBJECT_COUNT=12;
constexpr double TRI_ROTATE_ANGLE=360.0f/DRAW_OBJECT_COUNT;
#define USE_MATERIAL_FILE true //是否使用材质文件
class TestApp:public WorkObject
{
Material * material =nullptr;
struct
{
MaterialInstance * mi;
Mesh * mesh;
}render_obj[DRAW_OBJECT_COUNT]{};
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,CoordinateSystem2D::NDC,mtl::WithLocalToWorld::With);
#ifndef USE_MATERIAL_FILE
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureColor2D(&cfg); //走程序内置材质创建函数
material=db->CreateMaterial(mci);
#else
material=db->LoadMaterial("Std2D/PureColor2D",&cfg); //走材质文件加载
#endif//USE_MATERIAL_FILE
if(!material)
return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].mi=db->CreateMaterialInstance(material);
if(!render_obj[i].mi)
return(false);
Color4f color=GetColor4f((COLOR)(i+int(COLOR::Blue)),1.0);
render_obj[i].mi->WriteMIData(color); //设置MaterialInstance的数据
}
}
pipeline=CreatePipeline(material,InlinePipeline::Solid2D);
return pipeline;
}
bool InitVBOAndRenderList()
{
Primitive *prim=CreatePrimitive("Triangle",VERTEX_COUNT,material->GetDefaultVIL(),
{{VAN::Position, VF_V2F, position_data}});
if(!prim)
return(false);
db->Add(prim);
Matrix4f mat;
SceneNode *scene_root=GetSceneRoot(); ///<取得场景根节点
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].mesh=db->CreateMesh(prim,render_obj[i].mi,pipeline);
if(!render_obj[i].mesh)
return(false);
mat=rotate(deg2rad<double>(TRI_ROTATE_ANGLE*i),AxisVector::Z);
CreateComponent<MeshComponent>(mat,scene_root,render_obj[i].mesh);
}
return(true);
}
public:
using WorkObject::WorkObject;
bool Init() override
{
if(!InitMaterial())
return(false);
if(!InitVBOAndRenderList())
return(false);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("AutoInstance"),1024,1024);
}

View File

@ -1,115 +0,0 @@
// 该范例主要演示使用2D坐系统直接绘制一个渐变色的三角形,使用UBO传递Viewport信息
#include<hgl/WorkManager.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t VERTEX_COUNT=3;
static float position_data_float[VERTEX_COUNT][2]=
{
{0.5, 0.25},
{0.75, 0.75},
{0.25, 0.75}
};
static int16 position_data[VERTEX_COUNT][2]={};
constexpr uint8 color_data[VERTEX_COUNT*4]=
{
255,0,0,255,
0,255,0,255,
0,0,255,255
};
constexpr VAType POSITION_SHADER_FORMAT =VAT_IVEC2;
constexpr VkFormat POSITION_DATA_FORMAT =VF_V2I16;
constexpr VkFormat COLOR_DATA_FORMAT =VF_V4UN8;
class TestApp:public WorkObject
{
private:
MaterialInstance * material_instance =nullptr;
Mesh * mesh_triangle =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,
CoordinateSystem2D::Ortho,
mtl::WithLocalToWorld::With);
VILConfig vil_config;
cfg.position_format = POSITION_SHADER_FORMAT; //这里指定shader中使用ivec2当做顶点输入格式
// ^
// + 这上下两种格式要配套,否则会出错
// v
vil_config.Add(VAN::Position, POSITION_DATA_FORMAT); //这里指定VAB中使用RG16I当做顶点数据格式
vil_config.Add(VAN::Color, COLOR_DATA_FORMAT); //这里指定VAB中使用RGBA8UNorm当做颜色数据格式
material_instance=CreateMaterialInstance(mtl::inline_material::VertexColor2D,&cfg,&vil_config);
if(!material_instance)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
const auto ext=GetExtent();
for(uint i=0;i<VERTEX_COUNT;i++)
{
position_data[i][0]=position_data_float[i][0]*ext.width;
position_data[i][1]=position_data_float[i][1]*ext.height;
}
mesh_triangle=CreateMesh("Triangle",VERTEX_COUNT,material_instance,pipeline,
{
{VAN::Position,POSITION_DATA_FORMAT,position_data},
{VAN::Color, COLOR_DATA_FORMAT, color_data}
});
if(!mesh_triangle)
return(false);
return CreateComponent<MeshComponent>(GetSceneRoot(),mesh_triangle); //创建一个静态网格组件
}
public:
using WorkObject::WorkObject;
bool Init() override
{
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("Draw triangle use UBO"));
}

View File

@ -1,11 +1,6 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common)
SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h)
add_subdirectory(Basic)
add_subdirectory(Texture)
add_subdirectory(LightBasic)
add_subdirectory(Gizmo)
SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h)
add_subdirectory(Vulkan)
add_subdirectory(2dVector)
@ -22,3 +17,4 @@ macro(CreateProject name)
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example")
endmacro()
CreateProject(MaterialCreaterTest MaterialCreaterTest.cpp)

View File

@ -11,4 +11,3 @@ endmacro()
CreateProject(00.control_point_2d control_point_2d.cpp)
CreateProject(01.align_test align_test.cpp)
CreateProject(02.TextDrawTest DrawText.cpp)

View File

@ -1,24 +0,0 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Gizmo")
endmacro()
CreateProject(01_SimplestAxis SimplestAxis.cpp)
CreateProject(02_PlaneGrid3D PlaneGrid3D.cpp)
CreateProject(03_RayPicking RayPicking.cpp)
CreateProject(04_Gizmo3DTest GizmoTest.cpp
Gizmo.h
GizmoResource.h
GizmoResource.cpp
Gizmo3DMove.cpp
#Gizmo3DScale.cpp
#Gizmo3DRotate.cpp
)

View File

@ -1,43 +0,0 @@
#pragma once
#include<hgl/graph/VK.h>
VK_NAMESPACE_BEGIN
enum class GizmoColor:uint
{
Black=0,
White,
Red,
Green,
Blue,
Yellow,
ENUM_CLASS_RANGE(Black,Yellow)
};
enum class GizmoShape:uint
{
Square=0, //方块
Circle, //圆
Cube, //立方体
Sphere, //球
Cone, //圆锥
Cylinder, //圆柱
Torus, //圆环
ENUM_CLASS_RANGE(Square,Torus)
};
bool InitGizmoResource(RenderFramework *);
void FreeGizmoResource();
Mesh *GetGizmoMesh(const GizmoShape &shape,const GizmoColor &color);
SceneNode *GetGizmoMoveNode();
//SceneNode *GetGizmoScaleMesh();
//SceneNode *GetGizmoRotateMesh();
VK_NAMESPACE_END

View File

@ -1,152 +0,0 @@
/*
Gizmo move
ref: Blender 4
0 9-10
*----------------->>>>
|
|
| 5+
| +6
|
|
v
10
22
15,5
1
*/
#include"GizmoResource.h"
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/RenderFramework.h>
#include<hgl/component/MeshComponent.h>
VK_NAMESPACE_BEGIN
namespace
{
static SceneNode *sn_gizmo_move=nullptr;
}//namespace
SceneNode *GetGizmoMoveNode()
{
return sn_gizmo_move;
}
void ClearGizmoMoveNode()
{
SAFE_CLEAR(sn_gizmo_move);
}
bool InitGizmoMoveNode(RenderFramework *render_framework)
{
Mesh *sphere=GetGizmoMesh(GizmoShape::Sphere,GizmoColor::White);
Mesh *cylinder[3]
{
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Blue),
};
Mesh *cone[3]
{
GetGizmoMesh(GizmoShape::Cone,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Cone,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Cone,GizmoColor::Blue),
};
Mesh *square[3]=
{
GetGizmoMesh(GizmoShape::Square,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Square,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Square,GizmoColor::Blue)
};
if(!sphere)
return(false);
for(int i=0;i<3;i++)
{
if(!cylinder[i])
return(false);
if(!cone[i])
return(false);
if(!square[i])
return(false);
}
{
sn_gizmo_move=new SceneNode();
sn_gizmo_move->AttachComponent(render_framework->CreateComponent<MeshComponent>(sphere));
{
Transform tm;
const Vector3f one_scale(1);
const Vector3f square_scale(2);
const Vector3f cylinder_scale(GIZMO_CYLINDER_RADIUS,GIZMO_CYLINDER_RADIUS,GIZMO_CYLINDER_HALF_LENGTH);
{
tm.SetScale(cylinder_scale);
tm.SetTranslation(0,0,GIZMO_CYLINDER_OFFSET);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cylinder[2]); //Z 向上圆柱
tm.SetScale(one_scale);
tm.SetTranslation(0,0,GIZMO_CONE_OFFSET);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cone[2]); //Z 向上圆锥
tm.SetScale(square_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET,0);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,square[2]);
}
{
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::Y,90);
tm.SetTranslation(GIZMO_CYLINDER_OFFSET,0,0);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cylinder[0]); //X 向右圆柱
tm.SetScale(one_scale);
tm.SetTranslation(GIZMO_CONE_OFFSET,0,0);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cone[0]); //X 向右圆锥
tm.SetScale(square_scale);
tm.SetTranslation(0,GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,square[0]);
}
{
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::X,-90);
tm.SetTranslation(0,GIZMO_CYLINDER_OFFSET,0);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cylinder[1]); //Y 向前圆柱
tm.SetScale(one_scale);
tm.SetTranslation(0,GIZMO_CONE_OFFSET,0);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,cone[1]); //Y 向前圆锥
tm.SetScale(square_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,0,GIZMO_TWO_AXIS_OFFSET);
render_framework->CreateComponent<MeshComponent>(tm.GetMatrix(),sn_gizmo_move,square[1]);
}
}
}
if(!sn_gizmo_move)
return(false);
return(true);
}
VK_NAMESPACE_END

View File

@ -1,80 +0,0 @@
#include"GizmoResource.h"
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/TransformFaceToCamera.h>
VK_NAMESPACE_BEGIN
namespace
{
static StaticMesh *sm_gizmo_rotate=nullptr;
}//namespace
StaticMesh *GetGizmoRotateStaticMesh()
{
return sm_gizmo_rotate;
}
void ClearGizmoRotateStaticMesh()
{
SAFE_CLEAR(sm_gizmo_rotate);
}
bool InitGizmoRotateStaticMesh()
{
Mesh *torus[4]
{
GetGizmoMesh(GizmoShape::Torus,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Torus,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Torus,GizmoColor::Blue),
GetGizmoMesh(GizmoShape::Torus,GizmoColor::White),
};
for(auto *r:torus)
{
if(!r)
return(false);
}
{
SceneNode *root_node=new SceneNode();
{
Transform tm;
tm.SetScale(GIZMO_ARROW_LENGTH);
root_node->Add(new SceneNode(tm,torus[0]));
tm.SetRotation(AXIS::Z,90);
root_node->Add(new SceneNode(tm,torus[1]));
tm.SetRotation(AXIS::Y,90);
root_node->Add(new SceneNode(tm,torus[2]));
}
{
SceneNode *white_torus=new SceneNode(scale(13),torus[3]);
white_torus->SetLocalNormal(AxisVector::X);
TransformFaceToCamera *rotate_white_torus_tfc=new TransformFaceToCamera();
//暂时因为无法传入Camera所以无法正确计算朝向正在设计Actor/World结构
white_torus->GetTransform().AddTransform(rotate_white_torus_tfc);
root_node->Add(white_torus);
}
sm_gizmo_rotate=CreateGizmoStaticMesh(root_node);
}
if(!sm_gizmo_rotate)
return(false);
return(true);
}
VK_NAMESPACE_END

View File

@ -1,152 +0,0 @@
/*
Gizmo move
ref: Blender 4
0 9-10
*----------------->>>>
|
|
| 5+
| +6
|
|
v
10
22
15,5
1
*/
#include"GizmoResource.h"
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/InlineGeometry.h>
VK_NAMESPACE_BEGIN
namespace
{
static StaticMesh *sm_gizmo_scale=nullptr;
}//namespace
StaticMesh *GetGizmoScaleStaticMesh()
{
return sm_gizmo_scale;
}
void ClearGizmoScaleStaticMesh()
{
SAFE_CLEAR(sm_gizmo_scale);
}
bool InitGizmoScaleStaticMesh()
{
Mesh *center_cube=GetGizmoMesh(GizmoShape::Cube,GizmoColor::White);
Mesh *cylinder[3]
{
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Cylinder,GizmoColor::Blue),
};
Mesh *cube[3]
{
GetGizmoMesh(GizmoShape::Cube,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Cube,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Cube,GizmoColor::Blue),
};
Mesh *square[3]=
{
GetGizmoMesh(GizmoShape::Square,GizmoColor::Red),
GetGizmoMesh(GizmoShape::Square,GizmoColor::Green),
GetGizmoMesh(GizmoShape::Square,GizmoColor::Blue)
};
if(!center_cube)
return(false);
for(int i=0;i<3;i++)
{
if(!cylinder[i])
return(false);
if(!cube[i])
return(false);
if(!square[i])
return(false);
}
{
SceneNode *root_node=new SceneNode();
root_node->Add(new SceneNode(scale(GIZMO_CENTER_SPHERE_RADIUS*2),center_cube));
{
Transform tm;
const Vector3f one_scale(1);
const Vector3f plane_scale(2);
const Vector3f cylinder_scale(GIZMO_CYLINDER_RADIUS,GIZMO_CYLINDER_RADIUS,GIZMO_CYLINDER_HALF_LENGTH);
{
tm.SetScale(cylinder_scale);
tm.SetTranslation(0,0,GIZMO_CYLINDER_OFFSET);
root_node->Add(new SceneNode(tm,cylinder[2])); //Z 向上圆柱
tm.SetScale(one_scale);
tm.SetTranslation(0,0,GIZMO_CONE_OFFSET);
root_node->Add(new SceneNode(tm,cube[2])); //Z 向上圆锥
tm.SetScale(plane_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET,0);
root_node->Add(new SceneNode(tm,square[2]));
}
{
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::Y,90);
tm.SetTranslation(GIZMO_CYLINDER_OFFSET,0,0);
root_node->Add(new SceneNode(tm,cylinder[0])); //X 向右圆柱
tm.SetScale(one_scale);
tm.SetTranslation(GIZMO_CONE_OFFSET,0,0);
root_node->Add(new SceneNode(tm,cube[0])); //X 向右圆锥
tm.SetScale(plane_scale);
tm.SetTranslation(0,GIZMO_TWO_AXIS_OFFSET,GIZMO_TWO_AXIS_OFFSET);
root_node->Add(new SceneNode(tm,square[0]));
}
{
tm.SetScale(cylinder_scale);
tm.SetRotation(AxisVector::X,-90);
tm.SetTranslation(0,GIZMO_CYLINDER_OFFSET,0);
root_node->Add(new SceneNode(tm,cylinder[1])); //Y 向前圆柱
tm.SetScale(one_scale);
tm.SetTranslation(0,GIZMO_CONE_OFFSET,0);
root_node->Add(new SceneNode(tm,cube[1])); //Y 向前圆锥
tm.SetScale(plane_scale);
tm.SetTranslation(GIZMO_TWO_AXIS_OFFSET,0,GIZMO_TWO_AXIS_OFFSET);
root_node->Add(new SceneNode(tm,square[1]));
}
}
sm_gizmo_scale=CreateGizmoStaticMesh(root_node);
}
if(!sm_gizmo_scale)
return(false);
return(true);
}
VK_NAMESPACE_END

View File

@ -1,324 +0,0 @@
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VKPipeline.h>
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/VertexDataManager.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/color/Color.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/SceneNode.h>
#include<hgl/graph/RenderFramework.h>
#include"GizmoResource.h"
VK_NAMESPACE_BEGIN
bool InitGizmoMoveNode(RenderFramework *);
void ClearGizmoMoveNode();
//bool InitGizmoScaleMesh();
//void ClearGizmoScaleMesh();
//
//bool InitGizmoRotateMesh();
//void ClearGizmoRotateMesh();
namespace
{
static RenderFramework *render_framework=nullptr;
static RenderResource * gizmo_rr=nullptr;
struct GizmoResource
{
Material * mtl;
MaterialInstance * mi[size_t(GizmoColor::RANGE_SIZE)];
Pipeline * pipeline;
VertexDataManager * vdm;
PrimitiveCreater * prim_creater;
};
static GizmoResource gizmo_line{};
static GizmoResource gizmo_triangle{};
struct GizmoMesh
{
Primitive *prim;
Mesh *mesh[size_t(GizmoColor::RANGE_SIZE)];
};
GizmoMesh gizmo_mesh[size_t(GizmoShape::RANGE_SIZE)]{};
void InitGizmoMesh(const GizmoShape &gs,Primitive *prim,Pipeline *p)
{
if(!prim)
return;
GizmoMesh *gr=gizmo_mesh+size_t(gs);
gr->prim=prim;
for(uint i=0;i<uint(GizmoColor::RANGE_SIZE);i++)
gr->mesh[i]=CreateMesh(prim,gizmo_triangle.mi[i],p);
}
bool InitMI(GizmoResource *gr)
{
if(!gr||!gr->mtl)
return(false);
Color4f color;
for(uint i=0;i<uint(GizmoColor::RANGE_SIZE);i++)
{
color=GetColor4f(gizmo_color[i],1.0);
gr->mi[i]=gizmo_rr->CreateMaterialInstance(gr->mtl,nullptr,&color);
if(!gr->mi[i])
return(false);
}
return(true);
}
bool InitGizmoResource2D()
{
if(!gizmo_rr)
return(false);
VulkanDevice *device=render_framework->GetDevice();
VulkanDevAttr *dev_attr=device->GetDevAttr();
RenderPass *render_pass=render_framework->GetDefaultRenderPass();
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Lines);
cfg.local_to_world=true;
cfg.position_format=VAT_VEC3;
mtl::MaterialCreateInfo *mci=CreateVertexLuminance3D(dev_attr,&cfg);
if(!mci)
return(false);
gizmo_line.mtl=gizmo_rr->CreateMaterial("GizmoLine",mci);
if(!gizmo_line.mtl)
return(false);
gizmo_line.mtl->Update();
}
{
gizmo_line.pipeline=render_pass->CreatePipeline(gizmo_line.mtl,InlinePipeline::Solid3D);
if(!gizmo_line.pipeline)
return(false);
}
if(!InitMI(&gizmo_line))
return(false);
{
gizmo_line.vdm=new VertexDataManager(device,gizmo_line.mtl->GetDefaultVIL());
if(!gizmo_line.vdm)
return(false);
if(!gizmo_line.vdm->Init( HGL_SIZE_1MB, //最大顶点数量
HGL_SIZE_1MB, //最大索引数量
IndexType::U16)) //索引类型
return(false);
}
{
}
return(true);
}
bool InitGizmoResource3D()
{
if(!gizmo_rr)
return(false);
VulkanDevice *device=render_framework->GetDevice();
VulkanDevAttr *dev_attr=device->GetDevAttr();
RenderPass *render_pass=render_framework->GetDefaultRenderPass();
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Triangles);
cfg.local_to_world=true;
cfg.material_instance=true;
mtl::MaterialCreateInfo *mci=CreateGizmo3D(dev_attr,&cfg);
if(!mci)
return(false);
gizmo_triangle.mtl=gizmo_rr->CreateMaterial("GizmoTriangle",mci);
if(!gizmo_triangle.mtl)
return(false);
gizmo_triangle.mtl->Update();
}
{
gizmo_triangle.pipeline=render_pass->CreatePipeline(gizmo_triangle.mtl,InlinePipeline::Solid3D);
if(!gizmo_triangle.pipeline)
return(false);
}
if(!InitMI(&gizmo_triangle))
return(false);
{
gizmo_triangle.vdm=new VertexDataManager(device,gizmo_triangle.mtl->GetDefaultVIL());
if(!gizmo_triangle.vdm)
return(false);
if(!gizmo_triangle.vdm->Init( HGL_SIZE_1MB, //最大顶点数量
HGL_SIZE_1MB, //最大索引数量
IndexType::U16)) //索引类型
return(false);
}
{
gizmo_triangle.prim_creater=new PrimitiveCreater(gizmo_triangle.vdm);
if(!gizmo_triangle.prim_creater)
return(false);
}
{
using namespace inline_geometry;
{
InitGizmoMesh(GizmoShape::Square,CreatePlaneSqaure(gizmo_triangle.prim_creater),gizmo_triangle.pipeline);
}
{
CircleCreateInfo cci;
cci.center=Vector2f(0,0);
cci.radius=Vector2f(0.5,0.5);
cci.field_count=16;
cci.has_center=false;
InitGizmoMesh(GizmoShape::Circle,CreateCircle3DByIndexTriangles(gizmo_triangle.prim_creater,&cci),gizmo_triangle.pipeline);
}
{
CubeCreateInfo cci;
cci.normal=true;
cci.tangent=false;
cci.tex_coord=false;
InitGizmoMesh(GizmoShape::Cube,CreateCube(gizmo_triangle.prim_creater,&cci),gizmo_triangle.pipeline);
}
{
InitGizmoMesh(GizmoShape::Sphere,CreateSphere(gizmo_triangle.prim_creater,16),gizmo_triangle.pipeline);
}
{
ConeCreateInfo cci;
cci.radius =GIZMO_CONE_RADIUS; //圆锥半径
cci.halfExtend =1; //圆锤一半高度
cci.numberSlices=16; //圆锥底部分割数
cci.numberStacks=3; //圆锥高度分割数
InitGizmoMesh(GizmoShape::Cone,CreateCone(gizmo_triangle.prim_creater,&cci),gizmo_triangle.pipeline);
}
{
struct CylinderCreateInfo cci;
cci.halfExtend =1; //圆柱一半高度
cci.numberSlices=16; //圆柱底部分割数
cci.radius =1; //圆柱半径
InitGizmoMesh(GizmoShape::Cylinder,CreateCylinder(gizmo_triangle.prim_creater,&cci),gizmo_triangle.pipeline);
}
{
struct TorusCreateInfo tci;
tci.innerRadius=0.975;
tci.outerRadius=1.0;
tci.numberSlices=64;
tci.numberStacks=8;
InitGizmoMesh(GizmoShape::Torus,CreateTorus(gizmo_triangle.prim_creater,&tci),gizmo_triangle.pipeline);
}
ENUM_CLASS_FOR(GizmoShape,int,i)
{
if(!gizmo_mesh[i].prim)
return(false);
}
}
return(true);
}
}//namespace
bool InitGizmoResource(RenderFramework *rf)
{
if(!rf)
return(false);
render_framework=rf;
gizmo_rr=render_framework->GetRenderResource();
VulkanDevice *device=render_framework->GetDevice();
if(!InitGizmoResource3D())
return(false);
if(!InitGizmoResource2D())
return(false);
InitGizmoMoveNode(rf);
//InitGizmoScaleMesh();
//InitGizmoRotateMesh();
return(true);
}
void FreeGizmoResource()
{
//ClearGizmoRotateMesh();
//ClearGizmoScaleMesh();
ClearGizmoMoveNode();
for(GizmoMesh &gr:gizmo_mesh)
{
SAFE_CLEAR(gr.prim)
SAFE_CLEAR_OBJECT_ARRAY(gr.mesh)
}
SAFE_CLEAR(gizmo_triangle.prim_creater);
SAFE_CLEAR(gizmo_triangle.vdm);
SAFE_CLEAR(gizmo_line.prim_creater);
SAFE_CLEAR(gizmo_line.vdm);
}
Mesh *GetGizmoMesh(const GizmoShape &shape,const GizmoColor &color)
{
if(!gizmo_rr)
return(nullptr);
RANGE_CHECK_RETURN_NULLPTR(shape)
RANGE_CHECK_RETURN_NULLPTR(color)
return gizmo_mesh[size_t(shape)].mesh[size_t(color)];
}
VK_NAMESPACE_END

View File

@ -1,41 +0,0 @@
#pragma once
#include"Gizmo.h"
#include<hgl/color/Color.h>
VK_NAMESPACE_BEGIN
class SceneNode;
class PrimitiveCreater;
class MeshComponent;
constexpr const COLOR gizmo_color[size_t(GizmoColor::RANGE_SIZE)]=
{
COLOR::MozillaCharcoal,
COLOR::BlanchedAlmond,
COLOR::BlenderAxisRed,
COLOR::BlenderAxisGreen,
COLOR::BlenderAxisBlue,
COLOR::BlenderYellow,
};
constexpr const float GIZMO_ARROW_LENGTH =10.0f; ///<箭头整体长度
constexpr const float GIZMO_CENTER_SPHERE_RADIUS=1.0f; ///<中心球半径
constexpr const float GIZMO_CONE_LENGTH =1.0f; ///<圆锥高度
constexpr const float GIZMO_CONE_RADIUS =1.0f; ///<圆锥底部半径
constexpr const float GIZMO_CONE_OFFSET =GIZMO_ARROW_LENGTH-(GIZMO_CONE_LENGTH/2.0f); ///<圆锥偏移量
constexpr const float GIZMO_CYLINDER_RADIUS =0.25f; ///<圆柱半径
constexpr const float GIZMO_CYLINDER_LENGTH =GIZMO_ARROW_LENGTH-GIZMO_CENTER_SPHERE_RADIUS-GIZMO_CONE_LENGTH; ///<圆柱长度
constexpr const float GIZMO_CYLINDER_HALF_LENGTH=GIZMO_CYLINDER_LENGTH/2.0f; ///<圆柱一半长度
constexpr const float GIZMO_CYLINDER_OFFSET =GIZMO_CYLINDER_HALF_LENGTH+GIZMO_CENTER_SPHERE_RADIUS; ///<圆柱偏移量
constexpr const float GIZMO_TWO_AXIS_OFFSET =5.0F; ///<二轴调节点偏移量(方片或圆)
Mesh *GetGizmoMesh(const GizmoShape &gs,const GizmoColor &);
VK_NAMESPACE_END

View File

@ -1,132 +0,0 @@
#include<hgl/WorkManager.h>
#include"Gizmo.h"
#include<hgl/graph/Ray.h>
using namespace hgl;
using namespace hgl::graph;
const Vector3f GizmoPosition(0,0,0);
///**
//* 一种永远转向正面的变换节点
//*/
//class TransformBillboard:public TransformBase
//{
// CameraInfo *camera_info=nullptr;
// bool face_to_camera=false;
//
// ViewportInfo *viewport_info=nullptr;
// float fixed_scale=1.0;
//
//public:
//
// virtual void SetCameraInfo (CameraInfo * ci ){camera_info =ci;}
// virtual void SetViewportInfo(ViewportInfo * vi ){viewport_info =vi;}
//
// virtual void SetFaceToCamera(bool ftc ){face_to_camera=ftc;}
// virtual void SetFixedScale (const float size){fixed_scale =size;}
//
// virtual bool RefreshTransform(const Transform &tf=IdentityTransform) override
// {
// if(!camera_info)
// {
// return SceneNode::RefreshTransform(tf);
// }
//
// if(face_to_camera)
// {
// LocalTransform.SetRotation(CalculateFacingRotationQuat(GetWorldPosition(),camera_info->view,AxisVector::X));
// }
//
// if(viewport_info)
// {
// const float screen_height=viewport_info->GetViewportHeight();
//
// const Vector4f pos=camera_info->Project(GetWorldPosition());
//
// LocalTransform.SetScale(pos.w*fixed_scale/screen_height);
// }
//
// return SceneNode::RefreshTransform(tf);
// }
//};//class BillboardSceneNode:public SceneNode
class TestApp:public WorkObject
{
SceneNode *sm_move=nullptr;
//StaticMesh *sm_rotate=nullptr;
//StaticMesh *sm_scale=nullptr;
private:
bool InitGizmo()
{
if(!InitGizmoResource(GetRenderFramework()))
return(false);
sm_move =GetGizmoMoveNode();
//sm_rotate =GetGizmoRotateStaticMesh();
//sm_scale =GetGizmoScaleStaticMesh();
return(true);
}
void InitGizmoSceneTree()
{
SceneNode *root=GetSceneRoot();
root->Add(Duplication(sm_move));
//root.Add(Duplication(sm_rotate->GetScene()));
//root.CreateSubNode(sm_scale->GetScene());
}
public:
bool Init() override
{
if(!InitGizmo())
return(false);
InitGizmoSceneTree();
CameraControl *camera_control=GetCameraControl();
camera_control->SetPosition(Vector3f(32,32,32));
camera_control->SetTarget(Vector3f(0,0,0));
return(true);
}
using WorkObject::WorkObject;
~TestApp()
{
FreeGizmoResource();
}
//void BuildCommandBuffer(uint32 index) override
//{
// camera_control->Refresh();
//
// const CameraInfo *ci=camera_control->GetCameraInfo();
// const ViewportInfo *vi=GetViewportInfo();
// const float screen_height=vi->GetViewportHeight();
// const Vector4f pos=ci->Project(GizmoPosition);
// //{
// // Transform tm;
// // tm.SetScale(pos.w*16.0f/screen_height);
// // root.SetLocalTransform(tm);
// //}
//}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("Gizmo"),1280,720);
}

View File

@ -1,135 +0,0 @@
// PlaneGrid3D
#include<hgl/WorkManager.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/FirstPersonCameraControl.h>
#include<hgl/color/Color.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
class TestApp:public WorkObject
{
private:
Material * material =nullptr;
Pipeline * pipeline =nullptr;
Primitive * prim_plane_grid =nullptr;
MaterialInstance * material_instance[3]{};
private:
bool InitMDP()
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Lines);
cfg.local_to_world=true;
cfg.position_format=VAT_VEC2;
material=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!material)return(false);
VILConfig vil_config;
vil_config.Add(VAN::Luminance,VF_V1UN8);
Color4f GridColor;
COLOR ce=COLOR::BlenderAxisRed;
for(uint i=0;i<3;i++)
{
GridColor=GetColor4f(ce,1.0);
material_instance[i]=db->CreateMaterialInstance(material,&vil_config,&GridColor);
ce=COLOR((int)ce+1);
}
pipeline=CreatePipeline(material_instance[0],InlinePipeline::Solid3D);
return pipeline;
}
bool CreateRenderObject()
{
using namespace inline_geometry;
struct PlaneGridCreateInfo pgci;
pgci.grid_size.Set(32,32);
pgci.sub_count.Set(8,8);
pgci.lum=180;
pgci.sub_lum=255;
auto pc=GetPrimitiveCreater(material_instance[0]);
prim_plane_grid=CreatePlaneGrid2D(pc,&pgci);
return prim_plane_grid;
}
void Add(SceneNode *parent_node,MaterialInstance *mi,const Matrix4f &mat)
{
Mesh *ri=db->CreateMesh(prim_plane_grid,mi,pipeline);
if(!ri)
return;
CreateComponent<MeshComponent>(mat,parent_node,ri);
}
bool InitScene()
{
SceneNode *scene_root=GetSceneRoot(); //取得缺省场景根节点
Add(scene_root,material_instance[0],Matrix4f(1.0f));
Add(scene_root,material_instance[1],rotate(HGL_RAD_90,0,1,0));
Add(scene_root,material_instance[2],rotate(HGL_RAD_90,1,0,0));
CameraControl *camera_control=GetCameraControl();
camera_control->SetPosition(Vector3f(32,32,32));
camera_control->SetTarget(Vector3f(0,0,0));
// camera_control->SetReserveDirection(true,true); //反转x,y
return(true);
}
public:
using WorkObject::WorkObject;
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
}
bool Init() override
{
if(!InitMDP())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
};//class TestApp:public CameraAppFramework
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("PlaneGrid3D"),1280,720);
}

View File

@ -1,202 +0,0 @@
// RayPicking
#include<hgl/WorkManager.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/Ray.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VertexDataManager.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
static float position_data[2][3]=
{
{100,100,100},
{0,0,0}
};
static uint8 lumiance_data[2]={255,255};
static Color4f white_color(1,1,1,1);
static Color4f yellow_color(1,1,0,1);
class TestApp:public WorkObject
{
Color4f color;
DeviceBuffer *ubo_color=nullptr;
private:
Material * mtl_plane_grid =nullptr;
MaterialInstance * mi_plane_grid =nullptr;
Pipeline * pipeline_plane_grid =nullptr;
Primitive * prim_plane_grid =nullptr;
Material * mtl_line =nullptr;
MaterialInstance * mi_line =nullptr;
Pipeline * pipeline_line =nullptr;
Primitive * prim_line =nullptr;
VABMap * prim_line_vab_map =nullptr;
Ray ray;
private:
bool InitMaterialAndPipeline()
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Lines);
cfg.local_to_world=true;
VILConfig vil_config;
vil_config.Add(VAN::Luminance,VF_V1UN8);
{
cfg.position_format=VAT_VEC2;
mtl_plane_grid=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_plane_grid)return(false);
mi_plane_grid=db->CreateMaterialInstance(mtl_plane_grid,&vil_config,&white_color);
if(!mi_plane_grid)return(false);
pipeline_plane_grid=CreatePipeline(mi_plane_grid,InlinePipeline::Solid3D);
if(!pipeline_plane_grid)return(false);
}
{
cfg.position_format=VAT_VEC3;
mtl_line=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_line)return(false);
mi_line=db->CreateMaterialInstance(mtl_line,&vil_config,&yellow_color);
if(!mi_line)return(false);
pipeline_line=CreatePipeline(mi_line,InlinePipeline::Solid3D);
if(!pipeline_line)
return(false);
}
return(true);
}
Mesh *Add(SceneNode *parent_node,Primitive *r,MaterialInstance *mi,Pipeline *p)
{
Mesh *ri=db->CreateMesh(r,mi,p);
if(!ri)
{
LOG_ERROR(OS_TEXT("Create Mesh failed."));
return(nullptr);
}
CreateComponent<MeshComponent>(parent_node,ri);
return ri;
}
bool CreateRenderObject()
{
using namespace inline_geometry;
{
auto pc=GetPrimitiveCreater(mi_plane_grid);
struct PlaneGridCreateInfo pgci;
pgci.grid_size.Set(32,32);
pgci.sub_count.Set(8,8);
pgci.lum=128;
pgci.sub_lum=196;
prim_plane_grid=CreatePlaneGrid2D(pc,&pgci);
}
{
prim_line=CreatePrimitive("RayLine",2,mi_line->GetVIL(),
{
{VAN::Position, VF_V3F,position_data},
{VAN::Luminance,VF_V1UN8,lumiance_data}
});
prim_line_vab_map=prim_line->GetVABMap(VAN::Position);
}
return(true);
}
bool InitScene()
{
SceneNode *scene_root=GetSceneRoot(); //取得缺省场景根节点
Add(scene_root,prim_plane_grid,mi_plane_grid,pipeline_plane_grid);
Add(scene_root,prim_line,mi_line,pipeline_line);
CameraControl *camera_control=GetCameraControl();
camera_control->SetPosition(Vector3f(32,32,32));
camera_control->SetTarget(Vector3f(0,0,0));
return(true);
}
public:
using WorkObject::WorkObject;
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
}
bool Init() override
{
if(!InitMaterialAndPipeline())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
void Tick(double) override
{
Vector2i mouse_position;
if(!GetMouseCoord(&mouse_position))
return;
CameraControl *camera_control=GetCameraControl();
const CameraInfo *ci=camera_control->GetCameraInfo();
const ViewportInfo *vi=camera_control->GetViewportInfo();
ray.Set(mouse_position,ci,vi); //设置射线查询的屏幕坐标点
const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标
prim_line_vab_map->Write(&pos, //更新VAB上这个点的位置
1); //这里的1代表的数据数量,不是字节数
}
};//class TestApp:public CameraAppFramework
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("RayPicking"),1280,720);
}

View File

@ -1,100 +0,0 @@
// SimplestAxis
// 直接从0,0,0向三个方向画一条直线用于确认坐标轴方向
#include<hgl/WorkManager.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/FirstPersonCameraControl.h>
#include<hgl/color/Color.h>
#include<hgl/component/MeshComponent.h>
using namespace hgl;
using namespace hgl::graph;
class TestApp:public WorkObject
{
private:
Material * material =nullptr;
Pipeline * pipeline =nullptr;
Primitive * prim_axis =nullptr;
MaterialInstance * material_instance =nullptr;
private:
bool InitMDP()
{
mtl::Material3DCreateConfig cfg(PrimitiveType::Lines);
cfg.local_to_world=true;
material_instance=CreateMaterialInstance(mtl::inline_material::VertexColor3D,&cfg);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D);
return pipeline;
}
bool CreateRenderObject()
{
using namespace inline_geometry;
auto pc=GetPrimitiveCreater(material_instance);
inline_geometry::AxisCreateInfo aci;
prim_axis=CreateAxis(pc,&aci);
return prim_axis;
}
bool InitScene()
{
Mesh *ri=db->CreateMesh(prim_axis,material_instance,pipeline);
CreateComponent<MeshComponent>(GetSceneRoot(),ri);
CameraControl *camera_control=GetCameraControl();
camera_control->SetPosition(Vector3f(32,32,32));
camera_control->SetTarget(Vector3f(0,0,0));
// camera_control->SetReserveDirection(true,true); //反转x,y
return(true);
}
public:
using WorkObject::WorkObject;
~TestApp()
{
SAFE_CLEAR(prim_axis);
}
bool Init() override
{
if(!InitMDP())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
};//class TestApp:public CameraAppFramework
int os_main(int,os_char **)
{
return RunFramework<TestApp>(OS_TEXT("SimplestAxis"),1280,720);
}

View File

@ -1,333 +0,0 @@
// BlinnPhong direction light
#include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/Ray.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/mtl/BlinnPhong.h>
#include<hgl/graph/VertexDataManager.h>
#include<hgl/graph/PrimitiveCreater.h>
using namespace hgl;
using namespace hgl::graph;
static float lumiance_data[2]={1,1};
static Color4f white_color(1,1,1,1);
static mtl::blinnphong::SunLight sun_light=
{
Vector4f(1,1,1,0), //direction
Vector4f(1,0.95,0.9,1) //color
};
constexpr const COLOR AxisColor[4]=
{
//COLOR::Red, //X轴颜色
//COLOR::Green, //Y轴颜色
//COLOR::Blue, //Z轴颜色
COLOR::White, //全局颜色
COLOR::GhostWhite,
COLOR::BlanchedAlmond,
COLOR::AntiqueWhite
};
constexpr const os_char *tex_filename[]=
{
OS_TEXT("eucalyptus-cross-versailles.Tex2D"),
OS_TEXT("tints-ashton-green-stretcher.Tex2D"),
OS_TEXT("worn-clay-cobble-in-desert-stretcher.Tex2D"),
OS_TEXT("plain-grey-sheer.Tex2D"),
};
constexpr const size_t TexCount=sizeof(tex_filename)/sizeof(os_char *);
class TestApp:public SceneAppFramework
{
private: //plane grid
Material * mtl_vertex_lum =nullptr;
MaterialInstance * mi_plane_grid =nullptr;
Pipeline * p_line =nullptr;
Primitive * prim_plane_grid =nullptr;
private:
DeviceBuffer * ubo_sun =nullptr;
Texture2DArray * texture =nullptr;
Sampler * sampler =nullptr;
private: //sphere
Material * mtl_blinnphong =nullptr;
PrimitiveCreater * pc_blinnphong =nullptr;
VertexDataManager * vdm_blinnphong =nullptr;
MaterialInstance * mi_blinnphong[4]{};
Pipeline * p_blinnphong =nullptr;
Primitive * prim_sphere =nullptr;
Primitive * prim_cone =nullptr;
Primitive * prim_cylinder =nullptr;
private:
bool InitTexture()
{
texture=db->CreateTexture2DArray( "SeamlessBackground",
256,256, ///<纹理尺寸
TexCount, ///<纹理层数
PF_BC1_RGBUN, ///<纹理格式
false); ///<是否自动产生mipmaps
if(!texture)return(false);
OSString filename;
for(uint i=0;i<TexCount;i++)
{
filename=filesystem::MergeFilename(OS_TEXT("res/image/seamless"),tex_filename[i]);
if(!db->LoadTexture2DToArray(texture,i,filename))
return(false);
}
return(true);
}
bool InitVertexLumMP()
{
mtl::Material3DCreateConfig cfg(device->GetDevAttr(),"VertexLuminance3D",PrimitiveType::Lines);
cfg.local_to_world=true;
mtl_vertex_lum=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_vertex_lum)return(false);
mi_plane_grid=db->CreateMaterialInstance(mtl_vertex_lum,nullptr,&white_color);
if(!mi_plane_grid)return(false);
p_line=CreatePipeline(mtl_vertex_lum,InlinePipeline::Solid3D,PrimitiveType::Lines);
if(!p_line)
return(false);
return(true);
}
bool CreateBlinnPhongUBO()
{
ubo_sun=db->CreateUBO("sun",sizeof(sun_light),&sun_light);
if(!ubo_sun)return(false);
return(true);
}
bool InitBlinnPhongSunLightMP()
{
mtl::Material3DCreateConfig cfg(device->GetDevAttr(),"BlinnPhong3D",PrimitiveType::Triangles);
cfg.local_to_world=true;
cfg.material_instance=true;
mtl_blinnphong=db->LoadMaterial("Std3D/BlinnPhong/SunLightPureColorTexture",&cfg);
if(!mtl_blinnphong)return(false);
mtl_blinnphong->BindUBO(DescriptorSetType::Global,"sun",ubo_sun);
mtl_blinnphong->Update();
sampler=db->CreateSampler();
if(!mtl_blinnphong->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
struct MIData
{
Color4f color;
uint32 tex_id[4];
}mi_data;
constexpr const uint MIDataStride=sizeof(MIData);
for(uint i=0;i<4;i++)
{
mi_data.color=GetColor4f(AxisColor[i],4);
mi_data.tex_id[0]=i;
mi_blinnphong[i]=db->CreateMaterialInstance(mtl_blinnphong, //材质
nullptr, //顶点输入配置,这里使用nullptr即代表会使用默认配置那么结果将等同于上面的mtl_blinnphong->GetDefaultVIL()
&mi_data); //材质实例参数
if(!mi_blinnphong[i])return(false);
}
p_blinnphong=CreatePipeline(mtl_blinnphong,InlinePipeline::Solid3D,PrimitiveType::Triangles);
if(!p_blinnphong)
return(false);
return(true);
}
bool InitVDMAndPC()
{
vdm_blinnphong=new VertexDataManager(device,mtl_blinnphong->GetDefaultVIL());
if(!vdm_blinnphong->Init( 1024*1024, //VAB最大容量
1024*1024, //索引最大容量
IndexType::U16)) //索引类型
{
delete vdm_blinnphong;
vdm_blinnphong=nullptr;
return(false);
}
pc_blinnphong=new PrimitiveCreater(vdm_blinnphong);
//pc_blinnphong=new PrimitiveCreater(device,mtl_blinnphong->GetDefaultVIL());
return(true);
}
bool CreateRenderObject()
{
using namespace inline_geometry;
//Plane Grid
//{
// struct PlaneGridCreateInfo pgci;
// pgci.grid_size.Set(32,32);
// pgci.sub_count.Set(8,8);
// pgci.lum=0.5;
// pgci.sub_lum=0.75;
// prim_plane_grid=CreatePlaneGrid(pc_blinnphong,mtl_vertex_lum->GetDefaultVIL(),&pgci);
//}
//Sphere
prim_sphere=CreateSphere(pc_blinnphong,16);
//Cone
{
struct ConeCreateInfo cci;
cci.radius =1; //圆锥半径
cci.halfExtend =1; //圆锤一半高度
cci.numberSlices=16; //圆锥底部分割数
cci.numberStacks=8; //圆锥高度分割数
prim_cone=CreateCone(pc_blinnphong,&cci);
}
//Cyliner
{
struct CylinderCreateInfo cci;
cci.halfExtend =1.25; //圆柱一半高度
cci.numberSlices=16; //圆柱底部分割数
cci.radius =1.25f; //圆柱半径
prim_cylinder=CreateCylinder(pc_blinnphong,&cci);
}
return(true);
}
Mesh *Add(Primitive *r,MaterialInstance *mi,Pipeline *p,const Matrix4f &mat=Identity4f)
{
if(!r)
return(nullptr);
if(!mi)
return(nullptr);
if(!p)
return(nullptr);
Mesh *ri=db->CreateMesh(r,mi,p);
if(!ri)
{
LOG_ERROR("Create Mesh failed! Primitive: "+r->GetName());
return(nullptr);
}
render_root.CreateSubNode(mat,ri);
return ri;
}
bool InitScene()
{
//Add(prim_plane_grid,mi_plane_grid,p_line,Identity4f);
Add(prim_sphere, mi_blinnphong[0],p_blinnphong,translate(Vector3f(0,0,2)));
Add(prim_cone, mi_blinnphong[1],p_blinnphong);
Add(prim_cylinder, mi_blinnphong[2],p_blinnphong,translate(Vector3f(0,0,-5)));
camera->pos=Vector3f(32,32,32);
camera_control->SetTarget(Vector3f(0,0,0));
camera_control->Refresh();
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
bool Init(uint w,uint h)
{
if(!SceneAppFramework::Init(w,h))
return(false);
if(!InitTexture())
return(false);
//if(!InitVertexLumMP())
// return(false);
if(!CreateBlinnPhongUBO())
return(false);
if(!InitBlinnPhongSunLightMP())
return(false);
if(!InitVDMAndPC())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
~TestApp()
{
SAFE_CLEAR(prim_cone)
SAFE_CLEAR(prim_cylinder)
SAFE_CLEAR(prim_sphere)
SAFE_CLEAR(prim_plane_grid)
SAFE_CLEAR(pc_blinnphong)
SAFE_CLEAR(vdm_blinnphong)
}
};//class TestApp:public CameraAppFramework
int main(int,char **)
{
return RunApp<TestApp>(1280,720);
}

View File

@ -1,13 +0,0 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Light Basic")
endmacro()
CreateProject(01_BlinnPhongDirectionLight BlinnPhongDirectionLight.cpp)

View File

@ -0,0 +1,126 @@
#include<hgl/shadergen/MaterialCreateInfo.h>
using namespace hgl;
using namespace hgl::graph;
using namespace hgl::shadergen;
bool PureColor2DMaterial()
{
MaterialCreateInfo mc("PureColor2D",1,false); //一个新材质1个RT输出默认使用Vertex/Fragment shader
//vertex部分
{
ShaderCreateInfoVertex *vsc=mc.GetVS(); //获取vertex shader creater
//以下代码会被展开为
/*
layout(location=?) in vec3 Position; //位置属性
*/
vsc->AddInput("vec2","Position"); //添加一个vec3类型的position属性输入
vsc->SetShaderCodes(R"(
void main()
{
gl_Position=vec4(Position,0,1);
})");
}
//添加一个名称为ColorMaterial的UBO定义,其内部有一个vec4 color的属性
//该代码会被展开为
/*
struct ColorMaterial
{
vec4 color;
};
*/
mc.AddStruct("ColorMaterial","vec4 color;");
//添加一个UBO该代码会被展开为
/*
layout(set=?,binding=?) uniform ColorMaterial mtl;
*/
mc.AddUBO( VK_SHADER_STAGE_FRAGMENT_BIT, //这个UBO出现在fragment shader
DescriptorSetType::PerMaterial, //它属于材质合集
"ColorMaterial", //UBO名称为ColorMaterial
"mtl"); //UBO变量名称为mtl
//fragment部分
{
ShaderCreateInfoFragment *fsc=mc.GetFS(); //获取fragment shader creater
//以下代码会被展开为
/*
layout(location=?) out vec4 Color; //颜色输出
*/
fsc->AddOutput("vec4","Color"); //添加一个vec4类型的color属性输出
fsc->SetShaderCodes(R"(
void main()
{
Color=mtl.color;
})");
}
mc.CreateShader();
return(true);
}
bool VertexColor2DMaterial()
{
MaterialCreateInfo mc("VertexColor2D",1,false);
//vertex部分
{
ShaderCreateInfoVertex *vsc=mc.GetVS();
vsc->AddInput("vec2","Position");
vsc->AddInput("vec4","Color");
vsc->AddOutput("vec4","Color");
vsc->SetShaderCodes(R"(
void main()
{
Output.Color=Color;
gl_Position=vec4(Position,0,1);
})");
}
//fragment部分
{
ShaderCreateInfoFragment *fsc=mc.GetFS();
fsc->AddOutput("vec4","Color");
fsc->SetShaderCodes(R"(
void main()
{
Color=Input.Color;
})");
}
mc.CreateShader();
return(true);
}
namespace glsl_compiler
{
bool Init();
void Close();
}//namespace glsl_compiler
int main()
{
if(!glsl_compiler::Init())
return -1;
PureColor2DMaterial();
VertexColor2DMaterial();
glsl_compiler::Close();
return 0;
}

View File

@ -1,16 +0,0 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Texture")
endmacro()
CreateProject(05_texture_format texture_format_list.cpp)
CreateProject(06_texture_quad texture_quad.cpp)
CreateProject(07_texture_rect texture_rect.cpp)
CreateProject(08_texture_rect_array texture_rect_array.cpp)

View File

@ -1,136 +0,0 @@
// 画一个带纹理的矩形2D模式专用
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(VulkanDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
constexpr float position_data[4]=
{
0, //left
0, //top
1, //right
1 //bottom
};
constexpr float tex_coord_data[4]=
{
0,0,
1,1
};
class TestApp:public VulkanApplicationFramework
{
private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"RectTexture2D",PrimitiveType::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=false;
material=db->LoadMaterial("Std2D/RectTexture2D",&cfg);
if(!material)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,PrimitiveType::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"),true);
if(!texture)return(false);
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
material_instance=db->CreateMaterialInstance(material);
return(true);
}
bool InitVBO()
{
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Rectangle",1);
if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
render_obj=db->CreateMesh(&rpc,material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_obj);
return(true);
}
void Resize(uint w,uint h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -1,216 +0,0 @@
// 画一个带纹理的矩形2D模式专用
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
#include<hgl/filesystem/Filename.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
//Texture2D *CreateTexture2DFromFile(VulkanDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
float position_data[4]=
{
0, //left
0, //top
1, //right
1 //bottom
};
constexpr float tex_coord_data[4]=
{
0,0,
1,1
};
constexpr const os_char *tex_filename[]=
{
OS_TEXT("001-online resume.Tex2D"),
OS_TEXT("002-salary.Tex2D"),
OS_TEXT("003-application.Tex2D"),
OS_TEXT("004-job interview.Tex2D")
};
constexpr const size_t TexCount=sizeof(tex_filename)/sizeof(os_char *);
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Texture2DArray * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
Pipeline * pipeline =nullptr;
DeviceBuffer * tex_id_ubo =nullptr;
Primitive * prim_rectangle =nullptr;
struct
{
MaterialInstance * mi;
Mesh * mesh;
}render_obj[TexCount]{};
private:
bool InitTexture()
{
texture=db->CreateTexture2DArray( "freepik icons",
512,512, ///<纹理尺寸
TexCount, ///<纹理层数
PF_BC1_RGBAUN, ///<纹理格式
false); ///<是否自动产生mipmaps
if(!texture)return(false);
OSString filename;
for(uint i=0;i<TexCount;i++)
{
filename=filesystem::MergeFilename(OS_TEXT("res/image/icon/freepik"),tex_filename[i]);
if(!db->LoadTexture2DToArray(texture,i,filename))
return(false);
}
return(true);
}
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"RectTexture2DArray",PrimitiveType::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=true;
material=db->LoadMaterial("Std2D/RectTexture2DArray",&cfg);
if(!material)
return(false);
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,PrimitiveType::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
for(uint32_t i=0;i<TexCount;i++)
{
render_obj[i].mi=db->CreateMaterialInstance(material);
if(!render_obj[i].mi)
return(false);
render_obj[i].mi->WriteMIData(i); //设置MaterialInstance的数据
}
return(true);
}
bool InitVBOAndRenderList()
{
PrimitiveCreater rpc(device,material->GetDefaultVIL());
rpc.Init("Rectangle",1);
position_data[2]=1.0f/float(TexCount);
if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
prim_rectangle=rpc.Create();
Vector3f offset(1.0f/float(TexCount),0,0);
for(uint32_t i=0;i<TexCount;i++)
{
render_obj[i].mesh=db->CreateMesh(prim_rectangle,render_obj[i].mi,pipeline);
if(!render_obj[i].mesh)
return(false);
offset.x=position_data[2]*float(i);
render_root.CreateSubNode(translate(offset),render_obj[i].mesh);
}
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(prim_rectangle);
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH*TexCount,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitTexture())
return(false);
if(!InitMaterial())
return(false);
if(!InitVBOAndRenderList())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
void Resize(uint w,uint h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -5,7 +5,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/RenderList.h>
using namespace hgl;

View File

@ -10,11 +10,22 @@
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Vulkan/${group}")
endmacro()
#CreateProject("Basic" FragCoord FragCoordTest.cpp)
CreateProject("Basic" 1st_draw_triangle_in_NDC first_triangle.cpp)
CreateProject("Basic" 2nd_draw_triangle_use_UBO second_triangle.cpp)
CreateProject("Basic" 3rd_AutoInstance third_triangle.cpp)
CreateProject("Basic" 4th_AutoMergeMaterialInstance fourth_triangle.cpp)
#CreateProject("Basic" FragCoord FragCoordTest.cpp)
#CreateProject("Basic" indices_rect indices_rect.cpp)
#CreateProject("Basic" FullScreenTriangle FullScreenTriangle.cpp)
#CreateProject("Basic" InstanceTriangle InstanceTriangle.cpp)
CreateProject("Texture" TextureFormat TextureFormat.cpp)
#CreateProject("Texture" texture_rect texture_rect.cpp)
#CreateProject("Texture" HQFilterTexture HQFilterTexture.cpp)
#CreateProject(06.Geometry2D Geometry2D.cpp)
#CreateProject("Geometry2D" RectanglePrimitive RectanglePrimitive.cpp)
#CreateProject("Tile" DrawTile DrawTile.cpp)
#CreateProject("Tile" DrawText DrawText.cpp)

View File

@ -5,7 +5,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/RenderList.h>

View File

@ -103,7 +103,7 @@ private:
const VkFormat GetCandidateFormat(const VkFormat *fmt_list, const uint count)
{
auto pd = device->GetPhyDevice();
auto pd = device->GetPhysicalDevice();
for (uint i = 0; i < count; i++)
if (pd->IsColorAttachmentOptimal(fmt_list[i]))
@ -118,7 +118,7 @@ private:
const VkFormat GetDepthCandidateFormat()
{
auto pd = device->GetPhyDevice();
auto pd = device->GetPhysicalDevice();
for (VkFormat fmt : depth_candidate_format)
if (pd->IsDepthAttachmentOptimal(fmt))

View File

@ -4,7 +4,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKImageView.h>
@ -16,7 +16,7 @@ using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(VulkanDevice *device,const OSString &filename);
Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=1280;
@ -139,7 +139,7 @@ private:
#ifdef _DEBUG
{
auto da=device->GetDevAttr();
auto da=device->GetDeviceAttribute();
if(da->debug_maker)
{
@ -172,7 +172,7 @@ private:
#ifdef _DEBUG
{
auto da=device->GetDevAttr();
auto da=device->GetDeviceAttribute();
VkQueue q=*(gbuffer.rt->GetQueue());
VkFramebuffer fbo= gbuffer.rt->GetFramebuffer()->GetFramebuffer();
@ -229,7 +229,7 @@ private:
#ifdef _DEBUG
{
auto da=device->GetDevAttr();
auto da=device->GetDeviceAttribute();
if(da->debug_maker)
{

View File

@ -1,4 +1,4 @@
#include<hgl/io/LoadString.h>
#include<hgl/type/StringList.h>
#include<hgl/graph/font/TextRender.h>
#include"VulkanAppFramework.h"
@ -8,14 +8,14 @@ using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH =1280;
constexpr uint32_t SCREEN_HEIGHT=SCREEN_WIDTH/16*9;
class TestApp:public CameraAppFramework
class TestApp:public VulkanApplicationFramework
{
private:
TextRender * text_render =nullptr;
TextPrimitive * text_primitive =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
public:
@ -28,7 +28,7 @@ private:
bool InitTextRenderable()
{
U16String str;
UTF16String str;
LoadStringFromTextFile(str,OS_TEXT("res/text/DaoDeBible.txt"));
@ -44,7 +44,7 @@ private:
if(!text_primitive)
return(false);
render_obj=text_render->CreateMesh(text_primitive);
render_obj=text_render->CreateRenderable(text_primitive);
if(!render_obj)
return(false);
@ -61,21 +61,16 @@ public:
if(!InitTextRenderable())
return(false);
VulkanApplicationFramework::BuildCommandBuffer(render_obj);
BuildCommandBuffer(render_obj);
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
VulkanApplicationFramework::BuildCommandBuffer(render_obj);
}
void BuildCommandBuffer(uint32_t index)
{
VulkanApplicationFramework::BuildCommandBuffer(index,render_obj);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework

View File

@ -5,7 +5,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/RenderList.h>

View File

@ -0,0 +1,87 @@
// 全屏三角形
// 该范例用于演示使用索引画一个覆盖全屏的三角形但是不传递任何顶点信息顶点坐标在vertex shader中通过gl_VertexIndex计算出来。
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable *renderable =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/fullscreen"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles);
return pipeline;
}
bool InitVBO()
{
auto primitive=db->CreatePrimitive(3);
if(!primitive)return(false);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(renderable);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(renderable);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,160 @@
// 4.Geometry3D
#include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
class TestApp:public CameraAppFramework
{
Color4f color;
DeviceBuffer *ubo_color=nullptr;
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Pipeline * pipeline =nullptr;
Primitive * ro_plane_grid[3]{};
private:
bool InitMDP()
{
material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D"));
if(!material)return(false);
material_instance=db->CreateMaterialInstance(material);
if(!material_instance)return(false);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines);
if(!pipeline)
return(false);
return(true);
}
Renderable *Add(Primitive *r,const Matrix4f &mat)
{
Renderable *ri=db->CreateRenderable(r,material_instance,pipeline);
render_root.CreateSubNode(mat,ri);
return ri;
}
void CreateRenderObject()
{
using namespace inline_geometry;
struct PlaneGridCreateInfo pgci;
pgci.coord[0]=Vector3f(-100,-100,0);
pgci.coord[1]=Vector3f( 100,-100,0);
pgci.coord[2]=Vector3f( 100, 100,0);
pgci.coord[3]=Vector3f(-100, 100,0);
pgci.step.x=32;
pgci.step.y=32;
pgci.side_step.x=8;
pgci.side_step.y=8;
pgci.color.Set(0.5,0,0,1);
pgci.side_color.Set(1,0,0,1);
const VIL *vil=material_instance->GetVIL();
ro_plane_grid[0]=CreatePlaneGrid(db,vil,&pgci);
pgci.color.Set(0,0.5,0,1);
pgci.side_color.Set(0,1,0,1);
ro_plane_grid[1]=CreatePlaneGrid(db,vil,&pgci);
pgci.color.Set(0,0,0.5,1);
pgci.side_color.Set(0,0,1,1);
ro_plane_grid[2]=CreatePlaneGrid(db,vil,&pgci);
}
bool InitScene()
{
Add(ro_plane_grid[0],Matrix4f(1.0f));
Add(ro_plane_grid[1],rotate(HGL_RAD_90,0,1,0));
Add(ro_plane_grid[2],rotate(HGL_RAD_90,1,0,0));
camera->pos=Vector3f(200,200,200);
camera_control->SetTarget(Vector3f(0,0,0));
camera_control->Refresh();
render_root.RefreshMatrix();
render_list->Expend(camera->info,&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMDP())
return(false);
CreateRenderObject();
if(!InitScene())
return(false);
return(true);
}
void BuildCommandBuffer(uint32 index)
{
render_root.RefreshMatrix();
render_list->Expend(GetCameraInfo(),&render_root);
VulkanApplicationFramework::BuildCommandBuffer(index,render_list);
}
void Resize(int w,int h)override
{
CameraAppFramework::Resize(w,h);
VulkanApplicationFramework::BuildCommandBuffer(render_list);
}
};//class TestApp:public CameraAppFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -5,7 +5,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/Mesh.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/RenderList.h>
@ -109,7 +109,7 @@ private:
VK_SAMPLER_ADDRESS_MODE_REPEAT,
0.0f,
VK_TRUE,
device->GetPhyDevice()->GetMaxSamplerAnisotropy(),
device->GetPhysicalDevice()->GetMaxSamplerAnisotropy(),
false,
VK_COMPARE_OP_NEVER,
0.0f,

View File

@ -0,0 +1,103 @@
// Instance Triangle
// 基本的Instance绘制测试用例,不使用场景树
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_SIZE=512;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT][2]=
{
{0,0},
{0.25,-0.75},
{0,-1}
};
constexpr float color_data[VERTEX_COUNT][4]=
{ {1,0,0,1},
{0,1,0,1},
{0,0,1,1}
};
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2DNDC"));
if(!material_instance)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data )))return(false);
if(!primitive->Set(VAN::Color, db->CreateVBO(VF_V4F,VERTEX_COUNT,color_data )))return(false);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
if(!BuildCommandBuffer(render_obj))
return(false);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,191 @@
// 18.RayPicking
#include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/InlineGeometry.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/Camera.h>
#include<hgl/graph/Ray.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
static float position_data[2][3]=
{
{100,100,100},
{0,0,0}
};
static float color_data[2][4]=
{
{1,1,0,1},
{1,1,0,1}
};
class TestApp:public CameraAppFramework
{
Color4f color;
DeviceBuffer *ubo_color=nullptr;
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Pipeline * pipeline =nullptr;
Primitive * ro_plane_grid =nullptr;
Primitive * ro_line =nullptr;
VBO * vbo_pos =nullptr;
Ray ray;
private:
bool InitMDP()
{
material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D"));
if(!material)return(false);
material_instance=db->CreateMaterialInstance(material);
if(!material_instance)return(false);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines);
if(!pipeline)
return(false);
return(true);
}
Renderable *Add(Primitive *r,const Matrix4f &mat)
{
Renderable *ri=db->CreateRenderable(r,material_instance,pipeline);
render_root.CreateSubNode(mat,ri);
return ri;
}
bool CreateRenderObject()
{
using namespace inline_geometry;
{
struct PlaneGridCreateInfo pgci;
pgci.coord[0]=Vector3f(-100,-100,0);
pgci.coord[1]=Vector3f( 100,-100,0);
pgci.coord[2]=Vector3f( 100, 100,0);
pgci.coord[3]=Vector3f(-100, 100,0);
pgci.step.x=32;
pgci.step.y=32;
pgci.side_step.x=8;
pgci.side_step.y=8;
pgci.color.Set(0.25,0,0,1);
pgci.side_color.Set(1,0,0,1);
const VIL *vil=material_instance->GetVIL();
ro_plane_grid=CreatePlaneGrid(db,vil,&pgci);
}
{
ro_line=db->CreatePrimitive(2);
if(!ro_line)return(false);
if(!ro_line->Set(VAN::Position, vbo_pos=db->CreateVBO(VF_V3F,2,position_data )))return(false);
if(!ro_line->Set(VAN::Color, db->CreateVBO(VF_V4F,2,color_data )))return(false);
}
return(true);
}
bool InitScene()
{
Add(ro_plane_grid,Matrix4f(1.0f));
Add(ro_line,Matrix4f(1.0f));
camera->pos=Vector3f(100,100,50);
camera_control->SetTarget(Vector3f(0,0,0));
camera_control->Refresh();
render_root.RefreshMatrix();
render_list->Expend(camera->info,&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMDP())
return(false);
if(!CreateRenderObject())
return(false);
if(!InitScene())
return(false);
return(true);
}
void BuildCommandBuffer(uint32 index)
{
const CameraInfo &ci=GetCameraInfo();
ray.Set(GetMouseCoord(),&ci); //设置射线查询的屏幕坐标点
const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标
vbo_pos->Write(&pos,3*sizeof(float)); //更新VBO上这个点的位置
render_root.RefreshMatrix();
render_list->Expend(ci,&render_root);
VulkanApplicationFramework::BuildCommandBuffer(index,render_list);
}
void Resize(int w,int h)override
{
CameraAppFramework::Resize(w,h);
VulkanApplicationFramework::BuildCommandBuffer(render_list);
}
};//class TestApp:public CameraAppFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,117 @@
// 2.RectanglePrimivate
// 该示例是texture_rect的进化演示使用GeometryShader画矩形
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_SIZE=512;
constexpr uint32_t VERTEX_COUNT=1;
constexpr float BORDER=0.1f;
constexpr float position_data[4]=
{
SCREEN_SIZE*BORDER, SCREEN_SIZE*BORDER,
SCREEN_SIZE*(1.0-BORDER), SCREEN_SIZE*(1.0-BORDER)
};
constexpr float tex_coord_data[4]=
{
0,0,1,1
};
class TestApp:public VulkanApplicationFramework
{
private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
MaterialInstance * material_instance =nullptr;
Primitive * primitive =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/TextureRect2D"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles);
if(!pipeline)return(false);
texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"));
if(!texture)return(false);
sampler=db->CreateSampler();
if(!material_instance->BindImageSampler(DescriptorSetType::Value,"tex",texture,sampler))return(false);
return(true);
}
bool InitVBO()
{
primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
primitive->Set(VAN::Position,db->CreateVBO(VF_V4F,VERTEX_COUNT,position_data));
primitive->Set(VAN::TexCoord,db->CreateVBO(VF_V4F,VERTEX_COUNT,tex_coord_data));
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_obj);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -9,6 +9,32 @@ using namespace hgl::graph;
VK_NAMESPACE_USING;
constexpr char *texture_compress_name[]=
{
"NONE",
"S3TC",
"PVRTC",
"ETC1",
"ETC2",
"EAC",
"ATC",
"ASTC",
"YUV"
};
constexpr char *data_type_name[]
{
"NONE",
"UNORM",
"SNORM",
"USCALED",
"SSCALED",
"UINT",
"SINT",
"UFLOAT",
"SFLOAT",
"SRGB"
};//
VulkanInstance *InitVulkanInstance()
{
@ -38,8 +64,8 @@ int main(int,char **)
{
Window * win =nullptr;
VulkanInstance * inst =nullptr;
VulkanDevice * device =nullptr;
const VulkanPhyDevice * physical_device =nullptr;
GPUDevice * device =nullptr;
const GPUPhysicalDevice * physical_device =nullptr;
inst=InitVulkanInstance();
@ -66,14 +92,14 @@ int main(int,char **)
std::cout<<"Format [ID:"<<std::setw(10)<<vf->format<<"]["<<std::setw(16)<<vf->name<<"]";
if(vf->depth!=VulkanBaseType::NONE)
std::cout<<"[ Depth:"<<std::setw(8)<<VulkanBaseTypeName[size_t(vf->depth)]<<"]";
std::cout<<"[ Depth:"<<std::setw(8)<<data_type_name[size_t(vf->depth)]<<"]";
if(vf->stencil!=VulkanBaseType::NONE)
std::cout<<"[Stencil:"<<std::setw(8)<<VulkanBaseTypeName[size_t(vf->stencil)]<<"]";
std::cout<<"[Stencil:"<<std::setw(8)<<data_type_name[size_t(vf->stencil)]<<"]";
if((vf->depth==VulkanBaseType::NONE)
&&(vf->stencil==VulkanBaseType::NONE))
std::cout<<"[ Color:"<<std::setw(8)<<VulkanBaseTypeName[size_t(vf->color)]<<"]";
std::cout<<"[ Color:"<<std::setw(8)<<data_type_name[size_t(vf->color)]<<"]";
{
const VkFormatProperties fp=physical_device->GetFormatProperties(vf->format);
@ -88,7 +114,7 @@ int main(int,char **)
}
if(vf->compress_type!=TextureCompressType::NONE)
std::cout<<" use "<<TextureCompressTypeName[size_t(vf->compress_type)]<<" compress.";
std::cout<<" use "<<texture_compress_name[size_t(vf->compress_type)]<<" compress.";
else
std::cout<<std::setw(4)<<vf->bytes<<" bytes/pixel.";
@ -100,4 +126,4 @@ int main(int,char **)
delete inst;
return 0;
}
}

View File

@ -0,0 +1,167 @@
// first_triangle
// 该范例主要演示使用NDC坐标系直接绘制一个渐变色的三角形
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/math/HalfFloat.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data_float[VERTEX_COUNT*2]=
{
0.0, -0.5,
-0.5, 0.5,
0.5, 0.5
};
#define USE_HALF_FLOAT_POSITION
#ifdef USE_HALF_FLOAT_POSITION
constexpr VkFormat PositionFormat=VF_V2HF;
half_float position_data_hf[VERTEX_COUNT*2];
#define position_data position_data_hf
#else
constexpr VkFormat PositionFormat=VF_V2F;
#define position_data position_data_float
#endif//USE_HALF_FLOAT_POSITION
#define USE_UNORM8_COLOR
#ifdef USE_UNORM8_COLOR
constexpr uint8 color_data[VERTEX_COUNT*4]=
{ 255,0,0,255,
0,255,0,255,
0,0,255,255
};
constexpr VkFormat ColorFormat=VF_V4UN8;
#else
constexpr float color_data[VERTEX_COUNT*4]=
{ 1,0,0,1,
0,1,0,1,
0,0,1,1
};
constexpr VkFormat ColorFormat=VF_V4F;
#endif//USE_UNORM8_COLOR
class TestApp:public VulkanApplicationFramework
{
private:
#if defined(USE_HALF_FLOAT_POSITION)||defined(USE_UNORM8_COLOR)
VILConfig vil_config;
#endif
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
void InitVIL()
{
#ifdef USE_HALF_FLOAT_POSITION
vil_config.Add(VAN::Position,PositionFormat);
#endif//USE_HALF_FLOAT_POSITION
#ifdef USE_UNORM8_COLOR
vil_config.Add(VAN::Color,ColorFormat);
#endif//USE_HALF_FLOAT_POSITION
}
bool InitAutoMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2d");
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
material_instance=db->CreateMaterialInstance(mci,&vil_config);
return material_instance;
}
bool InitPipeline()
{
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
#ifdef USE_HALF_FLOAT_POSITION
Float32toFloat16(position_data_hf,position_data_float,VERTEX_COUNT*2);
#endif//USE_HALF_FLOAT_POSITION
if(!rpc.SetVBO(VAN::Position, PositionFormat, position_data))return(false);
if(!rpc.SetVBO(VAN::Color, ColorFormat, color_data ))return(false);
render_obj=rpc.Create(material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
InitVIL();
if(!InitAutoMaterial())
return(false);
if(!InitPipeline())
return(false);
if(!InitVBO())
return(false);
if(!BuildCommandBuffer(render_obj))
return(false);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,147 @@
// AutoMergeMaterialInstance
// 该范例主要演示使用一个材质下的不同材质实例传递颜色参数绘制三角形并依赖RenderList中的自动合并功能让同一材质下所有不同材质实例的对象一次渲染完成。
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
#include<hgl/color/Color.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1024;
constexpr uint32_t SCREEN_HEIGHT=1024;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT*2]=
{
0.0, 0.0,
-0.1, 0.9,
0.1, 0.9
};
constexpr uint DRAW_OBJECT_COUNT=12;
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Material * material =nullptr;
struct
{
MaterialInstance * mi;
Renderable * r;
}render_obj[DRAW_OBJECT_COUNT]{};
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureColor2D");
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=true;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureColor2D(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].mi=db->CreateMaterialInstance(material);
if(!render_obj[i].mi)
return(false);
Color4f color=GetColor4f((COLOR)(i+int(COLOR::Blue)),1.0);
render_obj[i].mi->WriteMIData(color,sizeof(Color4f)); //设置MaterialInstance的数据
}
}
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Triangles);
return pipeline;
}
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
if(!render_obj[i].r)
return(false);
render_root.CreateSubNode(rotate(deg2rad(360/DRAW_OBJECT_COUNT*i),Vector3f(0,0,1)),render_obj[i].r);
}
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,111 @@
// indices_rect
// 该示例演示使用索引数据画一个矩形,并使用了颜色材质
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
constexpr uint32_t VERTEX_COUNT=4;
static Vector4f color(1,1,1,1);
constexpr float position_data[VERTEX_COUNT][2]=
{
{0,0},
{SCREEN_WIDTH,0},
{0,SCREEN_HEIGHT},
{SCREEN_WIDTH,SCREEN_HEIGHT}
};
constexpr uint32_t INDEX_COUNT=6;
constexpr uint16 index_data[INDEX_COUNT]=
{
0,1,3,
0,3,2
};
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable *renderable =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/FragColor"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
auto primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(renderable);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(renderable);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,131 @@
// second_triangle
// 该范例主要演示使用2D坐系统直接绘制一个渐变色的三角形,使用UBO传递Viewport信息
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1280;
constexpr uint32_t SCREEN_HEIGHT=720;
constexpr uint32_t VERTEX_COUNT=3;
static float position_data[VERTEX_COUNT][2]=
{
{0.5, 0.25},
{0.75, 0.75},
{0.25, 0.75}
};
constexpr float color_data[VERTEX_COUNT][4]=
{
{1,0,0,1},
{0,1,0,1},
{0,0,1,1}
};
//#define USE_ZERO2ONE_COORD //使用左上角0,0右下角1,1的坐标系
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D");
#ifdef USE_ZERO2ONE_COORD
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
#else
cfg.coordinate_system=CoordinateSystem2D::Ortho;
#endif//USE_ZERO2ONE_COORD
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
material_instance=db->CreateMaterialInstance(mci);
if(!material_instance)
return(false);
db->global_descriptor.Bind(material_instance->GetMaterial());
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
#ifndef USE_ZERO2ONE_COORD //使用ortho坐标系
for(uint i=0;i<VERTEX_COUNT;i++)
{
position_data[i][0]*=SCREEN_WIDTH;
position_data[i][1]*=SCREEN_HEIGHT;
}
#endif//USE_ZERO2ONE_COORD
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVBO(VAN::Color, VF_V4F, color_data ))return(false);
render_obj=rpc.Create(material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
if(!BuildCommandBuffer(render_obj))
return(false);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -1,18 +1,17 @@
// 画一个带纹理的四边形
// 2.texture_rect
// 该示例是1.indices_rect的进化演示在矩形上贴上贴图
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(VulkanDevice *device,const OSString &filename);
Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=256;
@ -22,18 +21,26 @@ constexpr uint32_t VERTEX_COUNT=4;
constexpr float position_data[VERTEX_COUNT][2]=
{
{-1, -1},
{ 1, -1},
{ 1, 1},
{-1, 1},
{0, 0},
{SCREEN_WIDTH, 0},
{0, SCREEN_HEIGHT},
{SCREEN_WIDTH, SCREEN_HEIGHT}
};
constexpr float tex_coord_data[VERTEX_COUNT][2]=
{
{0,0},
{1,0},
{1,1},
{0,1}
{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
@ -42,28 +49,22 @@ private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * renderable =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"PureTexture2D",PrimitiveType::Fan);
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Texture2D"));
if(!material_instance)return(false);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
material=db->LoadMaterial("Std2D/PureTexture2D",&cfg);
if(!material)
return(false);
BindCameraUBO(material_instance);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,PrimitiveType::Fan); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -72,28 +73,23 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
material_instance=db->CreateMaterialInstance(material);
if(!material_instance->BindImageSampler(DescriptorSetType::Value,"tex",texture,sampler))return(false);
return(true);
}
bool InitVBO()
{
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Quad",VERTEX_COUNT);
auto primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!rpc.WriteVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
if(!primitive->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(VAN::TexCoord,db->CreateVBO(VF_V2F,VERTEX_COUNT,tex_coord_data)))return(false);
if(!primitive->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false);
render_obj=db->CreateMesh(&rpc,material_instance,pipeline);
return(render_obj);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
@ -109,16 +105,16 @@ public:
if(!InitVBO())
return(false);
BuildCommandBuffer(render_obj);
BuildCommandBuffer(renderable);
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
BuildCommandBuffer(renderable);
}
};//class TestApp:public VulkanApplicationFramework

View File

@ -0,0 +1,138 @@
// AutoInstance
// 该范例主要演示使用RenderList系统绘制多个三角形并利用RenderList进行排序以及自动合并进行Instance渲染
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=1024;
constexpr uint32_t SCREEN_HEIGHT=1024;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT*2]=
{
0.0, 0.0,
-0.1, 0.9,
0.1, 0.9
};
constexpr uint8 color_data[VERTEX_COUNT][4]=
{ {255,0,0,255},
{0,255,0,255},
{0,0,255,255}
};
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D");
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=true;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
VILConfig vil_config;
vil_config.Add(VAN::Color,VF_V4UN8);
material_instance=db->CreateMaterialInstance(mci,&vil_config);
}
if(!material_instance)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVBO(VAN::Color, VF_V4UN8, color_data ))return(false);
render_obj=rpc.Create(material_instance,pipeline);
if(!render_obj)
return(false);
for(uint i=0;i<12;i++)
render_root.CreateSubNode(rotate(deg2rad(30*i),Vector3f(0,0,1)),render_obj);
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -19,9 +19,6 @@
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VKRenderTarget.h>
#include<hgl/graph/VKRenderResource.h>
#ifdef _DEBUG
#include<hgl/graph/VKDeviceAttribute.h>
#endif//_DEBUG
#include<hgl/graph/RenderList.h>
#include<hgl/graph/mtl/UBOCommon.h>
#include<hgl/color/Color.h>
@ -53,9 +50,9 @@ protected:
protected:
VulkanDevice * device =nullptr;
GPUDevice * device =nullptr;
RenderPass * device_render_pass =nullptr;
SwapchainRenderTarget * sc_render_target =nullptr;
RTSwapchain * sc_render_target =nullptr;
protected:
@ -76,14 +73,6 @@ protected:
public:
virtual void BindRenderResource(RenderResource *rr)
{
if(!rr)
return;
rr->static_descriptor.AddUBO(mtl::SBS_ViewportInfo.name,ubo_vp_info);
}
virtual ~VulkanApplicationFramework()
{
CloseShaderCompiler();
@ -91,21 +80,21 @@ public:
win->Unjoin(this);
SAFE_CLEAR(db);
SAFE_CLEAR_OBJECT_ARRAY_OBJECT(cmd_buf,swap_chain_count);
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
SAFE_CLEAR(device);
SAFE_CLEAR(win);
SAFE_CLEAR(inst);
}
virtual bool Init(uint w,uint h)
virtual bool Init(int w,int h)
{
logger::InitLogger(OS_TEXT("VulkanTest"));
if(!InitShaderCompiler())
return(false);
SetClearColor(COLOR::MozillaCharcoal);
clear_color.Set(0,0,0,1);
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
@ -137,16 +126,10 @@ public:
return(false);
}
{
VulkanHardwareRequirement vh_req;
device=CreateRenderDevice(inst,win);
vh_req.wideLines=VulkanHardwareRequirement::SupportLevel::Want;
device=CreateRenderDevice(inst,win,&vh_req);
if(!device)
return(false);
}
if(!device)
return(false);
device_render_pass=device->GetRenderPass();
@ -159,30 +142,20 @@ public:
{
vp_info.Set(w,h);
ubo_vp_info=db->CreateUBO("Viewport",sizeof(ViewportInfo),&vp_info);
}
ubo_vp_info=db->CreateUBO(sizeof(ViewportInfo),&vp_info);
BindRenderResource(db);
db->global_descriptor.AddUBO(mtl::SBS_ViewportInfo.name,ubo_vp_info);
}
return(true);
}
virtual void Resize(uint w,uint h)
virtual void Resize(int w,int h)
{
vp_info.Set(w,h);
ubo_vp_info->Write(&vp_info);
}
ViewportInfo *GetViewportInfo()
{
return &vp_info;
}
DeviceBuffer *GetViewportInfoBuffer()
{
return ubo_vp_info;
}
void SetClearColor(const Color4f &cc)
{
clear_color=cc;
@ -205,7 +178,7 @@ public:
void InitCommandBuffer()
{
if(cmd_buf)
SAFE_CLEAR_OBJECT_ARRAY_OBJECT(cmd_buf,swap_chain_count);
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
sc_render_target=device->GetSwapchainRT();
@ -216,37 +189,51 @@ public:
cmd_buf=hgl_zero_new<RenderCmdBuffer *>(swap_chain_count);
for(int32_t i=0;i<swap_chain_count;i++)
cmd_buf[i]=device->CreateRenderCommandBuffer(device->GetPhyDevice()->GetDeviceName()+AnsiString(":RenderCmdBuffer_")+AnsiString::numberOf(i));
cmd_buf[i]=device->CreateRenderCommandBuffer();
}
}
bool BuildCommandBuffer(RenderCmdBuffer *cb,Framebuffer *fbo,Mesh *ri)
bool BuildCommandBuffer(RenderCmdBuffer *cb,RenderPass *rp,Framebuffer *fb,Renderable *ri)
{
if(!ri)return(false);
const VertexInputData *vid=ri->GetVertexInputData();
cb->Begin();
cb->BindFramebuffer(fbo);
cb->BindFramebuffer(rp,fb);
cb->SetClearColor(0,clear_color);
cb->BeginRenderPass();
cb->BindPipeline(ri->GetPipeline());
cb->BindDescriptorSets(ri->GetMaterial());
cb->BindDataBuffer(ri->GetDataBuffer());
cb->Draw(ri->GetDataBuffer(),ri->GetRenderData());
cb->BindVBO(ri);
if (vid->index_buffer->buffer)
cb->DrawIndexed(vid->index_buffer->buffer->GetCount());
else
cb->Draw(vid->vertex_count);
cb->EndRenderPass();
cb->End();
return(true);
}
bool BuildCommandBuffer(uint32_t index,Mesh *ri)
void BuildCommandBuffer(RenderCmdBuffer *cb,RenderTarget *rt,Renderable *ri)
{
if(!cb||!rt||!ri)
return;
BuildCommandBuffer(cb,rt->GetRenderPass(),rt->GetFramebuffer(),ri);
}
bool BuildCommandBuffer(uint32_t index,Renderable *ri)
{
if(!ri)return(false);
return BuildCommandBuffer(cmd_buf[index],
sc_render_target->GetFramebuffer(),ri);
return BuildCommandBuffer(cmd_buf[index],sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index),ri);
}
bool BuildCommandBuffer(Mesh *ri)
bool BuildCommandBuffer(Renderable *ri)
{
if(!ri)return(false);
@ -256,7 +243,7 @@ public:
return(true);
}
bool BuildCurrentCommandBuffer(Mesh *ri)
bool BuildCurrentCommandBuffer(Renderable *ri)
{
if(!ri)return(false);
@ -270,7 +257,7 @@ public:
RenderCmdBuffer *cb=cmd_buf[index];
cb->Begin();
cb->BindFramebuffer(sc_render_target->GetFramebuffer(index));
cb->BindFramebuffer(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index));
cb->SetClearColor(0,clear_color);
cb->BeginRenderPass();
rl->Render(cb);
@ -290,22 +277,7 @@ public:
}
template<typename ...ARGS>
Pipeline *CreatePipeline(ARGS...args)
{
Pipeline *p=device_render_pass->CreatePipeline(args...);
if(!p)
return(nullptr);
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
du->SetPipeline(*p,"Pipeline:"+p->GetName());
#endif//_DEBUG
return p;
}
Pipeline *CreatePipeline(ARGS...args){return device_render_pass->CreatePipeline(args...);}
public:
@ -346,8 +318,127 @@ public:
}
};//class VulkanApplicationFramework
class CameraKeyboardControl:public KeyboardStateEvent
{
FirstPersonCameraControl *camera;
float move_speed;
public:
CameraKeyboardControl(FirstPersonCameraControl *wc)
{
camera=wc;
move_speed=1.0f;
}
bool OnPressed(const KeyboardButton &kb)override
{
if(!KeyboardStateEvent::OnPressed(kb))
return(false);
if(kb==KeyboardButton::Minus )move_speed*=0.9f;else
if(kb==KeyboardButton::Equals )move_speed*=1.1f;
return(true);
}
void Update()
{
if(HasPressed(KeyboardButton::W ))camera->Forward (move_speed);else
if(HasPressed(KeyboardButton::S ))camera->Backward (move_speed);else
if(HasPressed(KeyboardButton::A ))camera->Left (move_speed);else
if(HasPressed(KeyboardButton::D ))camera->Right (move_speed);else
//if(HasPressed(KeyboardButton::R ))camera->Up (move_speed);else
//if(HasPressed(KeyboardButton::F ))camera->Down (move_speed);else
//if(HasPressed(KeyboardButton::Left ))camera->HoriRotate( move_speed);else
//if(HasPressed(KeyboardButton::Right ))camera->HoriRotate(-move_speed);else
//if(HasPressed(KeyboardButton::Up ))camera->VertRotate( move_speed);else
//if(HasPressed(KeyboardButton::Down ))camera->VertRotate(-move_speed);else
return;
}
};
class CameraMouseControl:public MouseEvent
{
FirstPersonCameraControl *camera;
double cur_time;
double last_time;
Vector2f mouse_pos;
Vector2f mouse_last_pos;
protected:
bool OnPressed(int x,int y,MouseButton) override
{
mouse_last_pos.x=x;
mouse_last_pos.y=y;
last_time=cur_time;
return(true);
}
bool OnWheel(int,int y) override
{
if(y==0)return(false);
camera->Forward(float(y)/10.0f);
return(true);
}
bool OnMove(int x,int y) override
{
mouse_pos.x=x;
mouse_pos.y=y;
bool left=HasPressed(MouseButton::Left);
bool right=HasPressed(MouseButton::Right);
Vector2f pos(x,y);
Vector2f gap=pos-mouse_last_pos;
if(left)
{
gap/=-5.0f;
camera->Rotate(gap);
}
else
if(right)
{
gap/=10.0f;
camera->Move(Vector3f(gap.x,0,gap.y));
}
last_time=cur_time;
mouse_last_pos=Vector2f(x,y);
return(true);
}
public:
CameraMouseControl(FirstPersonCameraControl *wc)
{
camera=wc;
cur_time=0;
}
const Vector2f &GetMouseCoord()const{return mouse_pos;}
void Update()
{
cur_time=GetDoubleTime();
}
};
class CameraAppFramework:public VulkanApplicationFramework
{
protected:
Camera * camera =nullptr;
@ -363,15 +454,6 @@ protected:
public:
virtual void BindRenderResource(RenderResource *rr) override
{
if(!rr)return;
VulkanApplicationFramework::BindRenderResource(rr);
rr->global_descriptor.AddUBO(mtl::SBS_CameraInfo.name,ubo_camera_info);
}
virtual ~CameraAppFramework()
{
SAFE_CLEAR(ckc);
@ -379,23 +461,17 @@ public:
SAFE_CLEAR(camera);
}
virtual bool Init(uint w,uint h) override
virtual bool Init(int w,int h)
{
if(!VulkanApplicationFramework::Init(w,h))
return(false);
InitCamera(w,h);
BindRenderResource(db);
return(true);
}
virtual void InitCamera(int w,int h)
{
camera=new Camera;
camera->pos=Vector3f(10,10,10);
camera_control=new FirstPersonCameraControl(&vp_info,camera);
camera_control->Refresh(); //更新矩阵计算
@ -406,21 +482,25 @@ public:
win->Join(ckc);
win->Join(cmc);
RefreshCameraInfo(camera_control->GetCameraInfo(),&vp_info,camera);
camera=new Camera;
camera->pos=Vector3f(10,10,10);
RefreshCameraInfo(&camera_control->GetCameraInfo(),&vp_info,camera);
ubo_camera_info=db->CreateUBO("CameraInfo",sizeof(CameraInfo),camera_control->GetCameraInfo());
ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&camera_control->GetCameraInfo());
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
vp_info.Set(w,h);
camera_control->Refresh();
ubo_camera_info->Write(camera_control->GetCameraInfo());
ubo_camera_info->Write(&camera_control->GetCameraInfo());
}
CameraInfo *GetCameraInfo()
const CameraInfo &GetCameraInfo()
{
return camera_control->GetCameraInfo();
}
@ -430,13 +510,18 @@ public:
return ubo_camera_info;
}
bool BindCameraUBO(MaterialInstance *mi)
{
return mi->BindUBO(DescriptorSetType::Global,"g_camera",ubo_camera_info);
}
virtual void BuildCommandBuffer(uint32_t index)=0;
virtual void Draw()override
{
camera_control->Refresh(); //更新相机矩阵
ubo_camera_info->Write(camera_control->GetCameraInfo()); //写入缓冲区
ubo_camera_info->Write(&camera_control->GetCameraInfo()); //写入缓冲区
const uint32_t index=AcquireNextImage();
@ -447,55 +532,4 @@ public:
ckc->Update();
cmc->Update();
}
};//class CameraAppFramework
class SceneAppFramework:public CameraAppFramework
{
protected:
SceneNode render_root;
RenderList * render_list =nullptr;
public:
SceneAppFramework()=default;
virtual ~SceneAppFramework()
{
SAFE_CLEAR(render_list);
}
virtual bool Init(uint width,uint height) override
{
if(!CameraAppFramework::Init(width,height))
return(false);
render_list=new RenderList(device);
return(true);
}
virtual void BuildCommandBuffer(uint32 index) override
{
VulkanApplicationFramework::BuildCommandBuffer(index,render_list);
}
virtual void Resize(uint w,uint h) override
{
CameraAppFramework::Resize(w,h);
VulkanApplicationFramework::BuildCommandBuffer(render_list);
}
};//class SceneAppFramework:public CameraAppFramework
template<typename T> int RunApp(uint w,uint h)
{
T app;
if(!app.Init(w,h))
return(-1);
while(app.Run());
return 0;
}
};//class CameraAppFramework

View File

@ -1,95 +0,0 @@
#pragma once
#include<hgl/WorkObject.h>
#include<hgl/graph/VKRenderTargetSwapchain.h>
namespace hgl
{
/**
* WorkObject<br>
*/
class WorkManager
{
protected:
graph::RenderFramework *render_framework;
uint fps=60;
double frame_time=1.0f/double(fps);
double last_update_time=0;
double last_render_time=0;
double cur_time=0;
WorkObject *cur_work_object=nullptr;
public:
WorkManager(graph::RenderFramework *rf)
{
render_framework=rf;
}
virtual ~WorkManager()
{
SAFE_CLEAR(cur_work_object);
}
void SetFPS(uint f)
{
fps=f;
frame_time=1.0f/double(fps);
}
void Tick(WorkObject *wo);
virtual void Render(WorkObject *wo);
void Run(WorkObject *wo);
};//class WorkManager
class SwapchainWorkManager:public WorkManager,public io::WindowEvent
{
graph::SwapchainModule *swapchain_module;
public:
SwapchainWorkManager(graph::RenderFramework *rf):WorkManager(rf)
{
swapchain_module=rf->GetSwapchainModule();
render_framework->Join(this);
}
~SwapchainWorkManager()
{
render_framework->Unjoin(this);
}
void Render(WorkObject *wo) override;
void OnResize(uint w,uint h) override;
};
template<typename WO> int RunFramework(const OSString &title,uint width=1280,uint height=720)
{
graph::RenderFramework rf(title);
if(!rf.Init(width,height))
return(-1);
SwapchainWorkManager wm(&rf);
WO *wo=new WO(&rf);
if(!wo->Init())
{
delete wo;
return(-2);
}
wm.Run(wo);
return 0;
}
}//namespcae hgl

View File

@ -1,123 +0,0 @@
#pragma once
#include<hgl/type/object/TickObject.h>
#include<hgl/graph/RenderFramework.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/mtl/MaterialLibrary.h>
#include<hgl/graph/Renderer.h>
#include<hgl/graph/Scene.h>
#include<hgl/Time.h>
//#include<iostream>
namespace hgl
{
namespace graph::mtl
{
class MaterialCreateInfo;
}
/**
* </p>
*
* WorkObject被定义为工作对象WorkObject的Render函数下
*/
class WorkObject:public TickObject
{
graph::RenderFramework *render_framework=nullptr;
bool destroy_flag=false;
bool render_dirty=true;
protected:
//以下数据均取自RenderFramework
graph::RenderResource *db=nullptr; //暂时的,未来会被更好的机制替代
graph::Scene * scene=nullptr; //场景
graph::Renderer * renderer=nullptr; //渲染器
public:
graph::RenderFramework * GetRenderFramework (){return render_framework;}
graph::VulkanDevice * GetDevice (){return render_framework->GetDevice();}
graph::VulkanDevAttr * GetDevAttr (){return render_framework->GetDevAttr();}
graph::TextureManager * GetTextureManager (){return render_framework->GetTextureManager();}
const VkExtent2D & GetExtent (){return renderer->GetExtent();}
graph::Scene * GetScene (){return scene;}
graph::SceneNode * GetSceneRoot (){return scene->GetRootNode();}
graph::Renderer * GetRenderer (){return renderer;}
graph::Camera * GetCamera (){return renderer->GetCamera();}
graph::CameraControl * GetCameraControl (){return render_framework->GetDefaultCameraControl();}
bool GetMouseCoord (Vector2i *mc)const{return render_framework->GetMouseCoord(mc);}
public:
const bool IsDestroy ()const{return destroy_flag;}
void MarkDestory(){destroy_flag=true;}
const bool IsRenderDirty ()const{return render_dirty;}
void MarkRenderDirty(){render_dirty=true;}
public:
WorkObject(graph::RenderFramework *,graph::Renderer *r=nullptr);
virtual ~WorkObject()=default;
virtual bool Init()=0;
virtual void OnRendererChange(graph::RenderFramework *rf,graph::Renderer *r);
virtual void OnResize(const VkExtent2D &){}
virtual void Tick(double){}
virtual void Render(double delta_time);
public:
#define WO_FUNC_FROM_RENDER_FRAMEWORK(name,return_type) template<typename ...ARGS> return_type name(ARGS...args){return render_framework?render_framework->name(args...):nullptr;}
WO_FUNC_FROM_RENDER_FRAMEWORK(CreatePipeline,graph::Pipeline *)
WO_FUNC_FROM_RENDER_FRAMEWORK(CreateMaterialInstance,graph::MaterialInstance *)
WO_FUNC_FROM_RENDER_FRAMEWORK(GetPrimitiveCreater,SharedPtr<graph::PrimitiveCreater>)
#undef WO_FUNC_FROM_RENDER_FRAMEWORK
graph::Primitive *CreatePrimitive(const AnsiString &name,
const uint32_t vertices_count,
const graph::VIL *vil,
const std::initializer_list<graph::VertexAttribDataPtr> &vad_list)
{
return render_framework?render_framework->CreatePrimitive(name,vertices_count,vil,vad_list):nullptr;
}
graph::Mesh *CreateMesh(const AnsiString &name,
const uint32_t vertices_count,
graph::MaterialInstance *mi,
graph::Pipeline *pipeline,
const std::initializer_list<graph::VertexAttribDataPtr> &vad_list)
{
return render_framework?render_framework->CreateMesh(name,vertices_count,mi,pipeline,vad_list):nullptr;
}
public: //Component 相关
template<typename C,typename ...ARGS>
inline C *CreateComponent(ARGS...args)
{
return render_framework?render_framework->CreateComponent<C>(args...):nullptr; //创建组件
}
};//class WorkObject
/**
* .
* WorkObject的基础上再提供RenderWorkObject派生类
*
*
* 使WorkObject
* */
}//namespcae hgl

View File

@ -1,178 +0,0 @@
#pragma once
#include<hgl/type/DataType.h>
#include<hgl/type/SortedSet.h>
#include<hgl/type/ArrayList.h>
/**
* Component/Data/Manager
*
* AMD FidelityFX
*
* AMD FidelityFX中Component存放于Entity下SceneNode
* Entity还是SceneNodeComponent的管理
* AMD FidelityFX中的SceneScene
*
* ComponentData是每个Component的数据Component或是其它模块提供数据
* ComponentManager是Component的管理器Component的创建
*
* AMD FidelityFX一样ComponentManager与Scene基本无关
* World之中
* Scene密切相关的Component它对应的Manager才会出现在Scene中CameraManager/LightManager
* MeshComponent之类的纯资源型就会是独立存在的
*
* Component是组件的基类
*
* SceneComponent是场景组件基类
*
* PrimitiveComponent是图元组件的基类
* Component都必须是一个有3D空间的几何图元
* PrimitiveComponent提供数据进行计算
* RenderComponent是可渲染组件的基类
*
* MeshComponent是静态网格组件RenderComponent实现
*
*/
#define COMPONENT_NAMESPACE hgl::graph
#define COMPONENT_NAMESPACE_BEGIN namespace COMPONENT_NAMESPACE {
#define COMPONENT_NAMESPACE_END }
COMPONENT_NAMESPACE_BEGIN
class ComponentManager;
class SceneNode;
struct ComponentData
{
public:
ComponentData()=default;
virtual ~ComponentData()=default;
};//struct ComponentData
using ComponentDataPtr=SharedPtr<ComponentData>;
/**
* <br>
*
*/
class Component
{
static uint unique_id_count;
uint unique_id;
SceneNode * OwnerNode;
ComponentManager * Manager;
ComponentDataPtr Data;
protected:
friend class ComponentManager;
virtual void OnDetachManager(ComponentManager *cm)
{
if(cm==Manager)
Manager=nullptr;
}
public:
Component()=delete;
Component(ComponentDataPtr,ComponentManager *);
virtual ~Component();
virtual const size_t GetHashCode()const=0;
public:
uint GetUniqueID ()const{return unique_id;}
SceneNode * GetOwnerNode()const{return OwnerNode;}
ComponentManager * GetManager ()const{return Manager;}
ComponentDataPtr GetData ()const{return Data;}
public:
virtual Component *Duplication();
//virtual void Update(const double delta_time)=0;
public: //事件
virtual void OnAttach(SceneNode *node){if(node)OwnerNode=node;} ///<附加到节点事件
virtual void OnDetach(SceneNode *){OwnerNode=nullptr;} ///<从节点分离事件
virtual void OnFocusLost(){} ///<焦点丢失事件
virtual void OnFocusGained(){} ///<焦点获得事件
};//class Component
#define COMPONENT_CLASS_BODY(name) static name##ComponentManager *GetDefaultManager () {return name##ComponentManager::GetDefaultManager();} \
name##ComponentManager *GetManager ()const {return (name##ComponentManager *)Component::GetManager();} \
static constexpr const size_t StaticHashCode () {return hgl::GetTypeHash<name##Component>();} \
const size_t GetHashCode ()const override{return name##Component::StaticHashCode();}
using ComponentSet=SortedSet<Component *>;
using ComponentList=ArrayList<Component *>;
class ComponentManager
{
ComponentSet component_set;
protected:
friend class Component; //Component可以直接访问ComponentManager的成员
virtual void AttachComponent(Component *c){if(!c)return;component_set.Add(c);}
virtual void DetachComponent(Component *c){if(!c)return;component_set.Delete(c);}
public:
virtual const size_t GetComponentHashCode()const=0;
virtual const size_t GetHashCode()const=0;
virtual ~ComponentManager();
public:
virtual Component * CreateComponent(ComponentDataPtr)=0;
const size_t GetComponentCount()const{return component_set.GetCount();}
ComponentSet & GetComponents(){return component_set;}
int GetComponents(ComponentList &comp_list,SceneNode *);
virtual void UpdateComponents(const double delta_time);
public: //事件
virtual void OnFocusLost(){} ///<焦点丢失事件
virtual void OnFocusGained(){} ///<焦点获得事件
};//class ComponentManager
#define COMPONENT_MANAGER_CLASS_BODY(name) static name##ComponentManager * GetDefaultManager () {return GetComponentManager<name##ComponentManager>(true);} \
static constexpr const size_t StaticHashCode () {return hgl::GetTypeHash<name##ComponentManager>();} \
static constexpr const size_t StaticComponentHashCode () {return hgl::GetTypeHash<name##Component>();} \
const size_t GetComponentHashCode ()const override{return name##ComponentManager::StaticComponentHashCode();} \
const size_t GetHashCode ()const override{return name##ComponentManager::StaticHashCode();} \
bool RegistryComponentManager(ComponentManager *);
ComponentManager *GetComponentManager(const size_t hash_code);
template<typename T> inline T *GetComponentManager(bool create_default=true)
{
T *cm=(T *)GetComponentManager(T::StaticHashCode());
if(!cm&&create_default)
{
cm=new T;
RegistryComponentManager(cm);
}
return cm;
}
COMPONENT_NAMESPACE_END

View File

@ -1,90 +0,0 @@
#pragma once
#include<hgl/component/RenderComponent.h>
#include<hgl/graph/Mesh.h>
//#include<hgl/log/LogInfo.h>
COMPONENT_NAMESPACE_BEGIN
struct MeshComponentData:public ComponentData
{
//static uint unique_id_count;
//uint unique_id;
Mesh *mesh;
public:
MeshComponentData()
{
mesh=nullptr;
// unique_id=++unique_id_count;
// LOG_INFO(AnsiString("MeshComponentData():")+AnsiString::numberOf(unique_id));
}
MeshComponentData(Mesh *m)
{
mesh=m;
// unique_id=++unique_id_count;
// LOG_INFO(AnsiString("MeshComponentData(Mesh *):")+AnsiString::numberOf(unique_id));
}
virtual ~MeshComponentData();
};//struct MeshComponentData
class MeshComponent;
class MeshComponentManager:public ComponentManager
{
public:
COMPONENT_MANAGER_CLASS_BODY(Mesh)
public:
MeshComponentManager()=default;
Component *CreateComponent(ComponentDataPtr cdp) override;
MeshComponent *CreateComponent(Mesh *);
};//class MeshComponentManager
class MeshComponent:public RenderComponent
{
WeakPtr<ComponentData> sm_data;
public:
COMPONENT_CLASS_BODY(Mesh)
public:
MeshComponent(ComponentDataPtr cdp,MeshComponentManager *cm):RenderComponent(cdp,cm)
{
sm_data=cdp;
}
virtual ~MeshComponent()=default;
MeshComponentData *GetData() {return dynamic_cast< MeshComponentData *>(sm_data.get());}
const MeshComponentData *GetData()const {return dynamic_cast<const MeshComponentData *>(sm_data.const_get());}
Mesh *GetMesh()const
{
if(!sm_data.valid())
return(nullptr);
const MeshComponentData *mcd=dynamic_cast<const MeshComponentData *>(sm_data.const_get());
if(!mcd)
return(nullptr);
return mcd->mesh;
}
};//class MeshComponent
COMPONENT_NAMESPACE_END

View File

@ -1,20 +0,0 @@
#pragma once
#include<hgl/component/SceneComponent.h>
COMPONENT_NAMESPACE_BEGIN
/**
* <br>
*
*/
class PrimitiveComponent:public SceneComponent
{
public:
using SceneComponent::SceneComponent;
virtual ~PrimitiveComponent()=default;
};//class PrimitiveComponent
COMPONENT_NAMESPACE_END

View File

@ -1,18 +0,0 @@
#pragma once
#include<hgl/component/PrimitiveComponent.h>
COMPONENT_NAMESPACE_BEGIN
/**
*
*/
class RenderComponent:public PrimitiveComponent
{
public:
using PrimitiveComponent::PrimitiveComponent;
virtual ~RenderComponent()=default;
};//class RenderComponent
COMPONENT_NAMESPACE_END

View File

@ -1,31 +0,0 @@
#pragma once
#include<hgl/component/Component.h>
#include<hgl/graph/SceneOrient.h>
COMPONENT_NAMESPACE_BEGIN
/**
* <br>
*
*/
class SceneComponent:public Component,public SceneOrient
{
public:
using Component::Component;
virtual ~SceneComponent()=default;
virtual Component *Duplication() override
{
SceneComponent *sc=(SceneComponent *)Component::Duplication();
if(!sc)
return(sc);
sc->SetLocalMatrix(GetLocalMatrix());
return sc;
}
};//class SceneComponent
COMPONENT_NAMESPACE_END

View File

@ -1,7 +1,7 @@
#ifndef HGL_DB_FIELD_TYPE_INCLUDE
#define HGL_DB_FIELD_TYPE_INCLUDE
#include<hgl/type/ArrayList.h>
#include<hgl/type/List.h>
#include<hgl/type/StringList.h>
namespace hgl
{

View File

@ -7,7 +7,7 @@ namespace hgl
namespace graph
{
/**
* 2D位图加载类
* 2Dλͼ¼ÓÔØ
*/
class Bitmap2DLoader:public Texture2DLoader
{
@ -20,8 +20,8 @@ namespace hgl
Bitmap2DLoader():Texture2DLoader(){}
~Bitmap2DLoader();
void *OnBegin(uint32 total_bytes,const VkFormat &) override;
bool OnEnd() override {return(false);}
void *OnBegin(uint32 total_bytes) override;
void OnEnd() override {}
BitmapData *GetBitmap();
};//class Bitmap2DLoader

View File

@ -1,28 +1,17 @@
#pragma once
#include<hgl/TypeFunc.h>
namespace hgl::graph
namespace hgl
{
enum class CoordinateSystem2D
namespace graph
{
NDC,
ZeroToOne, //左上角为0,0右下角为1,1
Ortho, //左上角为0,0右下角为(width-1),(height-1)
enum class CoordinateSystem2D
{
NDC,
ZeroToOne, //左上角为0,0右下角为1,1
Ortho, //左上角为0,0右下角为(width-1),(height-1)
ENUM_CLASS_RANGE(NDC,Ortho)
};
constexpr const char *CoordinateSystem2DName[]=
{
"NDC",
"0to1",
"Ortho"
};
inline const char *GetCoordinateSystem2DName(const enum class CoordinateSystem2D &cs)
{
RANGE_CHECK_RETURN_NULLPTR(cs)
return CoordinateSystem2DName[size_t(cs)];
}
}//namespace hgl::graph
ENUM_CLASS_RANGE(NDC,Ortho)
};
}//namespace graph
}//namespace hgl

View File

@ -4,15 +4,12 @@
#include<hgl/graph/VK.h>
#include<hgl/math/Vector.h>
#include<hgl/type/RectScope.h>
#include<hgl/type/Size2.h>
#include<hgl/color/Color4f.h>
#include<hgl/graph/AABB.h>
namespace hgl
{
namespace graph
{
class PrimitiveCreater;
namespace inline_geometry
{
/**
@ -23,12 +20,12 @@ namespace hgl
RectScope2f scope;
};//struct RectangleCreateInfo
Primitive *CreateRectangle(PrimitiveCreater *pc,const RectangleCreateInfo *rci);
Primitive *CreateRectangle(RenderResource *db,const VIL *vil,const RectangleCreateInfo *rci);
/**
*
*/
Primitive *CreateGBufferCompositionRectangle(PrimitiveCreater *pc);
Primitive *CreateGBufferCompositionRectangle(RenderResource *db,const VIL *vil);
/**
* (/线)
@ -39,7 +36,7 @@ namespace hgl
uint32_t round_per; ///<圆角精度
};//struct RoundRectangleCreateInfo:public RectangleCreateInfo
Primitive *CreateRoundRectangle(PrimitiveCreater *pc,const RoundRectangleCreateInfo *rci);
Primitive *CreateRoundRectangle(RenderResource *db,const VIL *vil,const RoundRectangleCreateInfo *rci);
/**
*
@ -48,9 +45,9 @@ namespace hgl
{
Vector2f center; ///<圆心坐标
Vector2f radius; ///<半径
uint field_count=8; ///<分段
uint field_count=8; ///<分段
bool has_center; ///<是否有圆心点
bool has_color =false;
Vector4f center_color; ///<圆心颜色
Vector4f border_color; ///<边缘颜色
@ -59,43 +56,44 @@ namespace hgl
/**
* 2D圆形(/线)
*/
Primitive *CreateCircle2D(PrimitiveCreater *pc,const CircleCreateInfo *cci);
/**
* 3D圆形(/XYZ永远为0)
*/
Primitive *CreateCircle3D(PrimitiveCreater *pc,const CircleCreateInfo *cci);
Primitive *CreateCircle(RenderResource *db,const VIL *vil,const CircleCreateInfo *cci);
/**
* 使3D圆形(/XYZ永远为0)
*/
Primitive *CreateCircle3DByIndexTriangles(PrimitiveCreater *pc,const CircleCreateInfo *cci);
/**
* <br>
* XY平面上居中的网格1
*
*/
struct PlaneGridCreateInfo
{
Size2u grid_size; ///<格子数量
Vector3f coord[4];
Vector2u step;
Size2u sub_count; ///<细分格子数量
Vector2u side_step; //到边界的步数
uint8 lum; ///<一般线条亮度
uint8 sub_lum; ///<细分及边界线条亮度
Color4f color; //一般线条颜色
Color4f side_color; //边界线条颜色
};//struct PlaneGridCreateInfo
/**
* (线)
*/
Primitive *CreatePlaneGrid2D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci); //创建一个平面网格(线条)
Primitive *CreatePlaneGrid(RenderResource *db,const VIL *vil,const PlaneGridCreateInfo *pgci);
Primitive *CreatePlaneGrid3D(PrimitiveCreater *pc,const PlaneGridCreateInfo *pgci);
struct PlaneCreateInfo
{
Vector2f tile;
public:
PlaneCreateInfo()
{
tile.x=1.0f;
tile.y=1.0f;
}
};//struct PlaneCreateInfo
/**
* ()
* ()
*/
Primitive *CreatePlaneSqaure(PrimitiveCreater *pc);
Primitive *CreatePlane(RenderResource *db,const VIL *vil,const PlaneCreateInfo *pci);
struct CubeCreateInfo
{
@ -131,7 +129,7 @@ namespace hgl
/**
* ()
*/
Primitive *CreateCube(PrimitiveCreater *pc,const CubeCreateInfo *cci);
Primitive *CreateCube(RenderResource *db,const VIL *vil,const CubeCreateInfo *cci);
struct BoundingBoxCreateInfo
{
@ -162,17 +160,17 @@ namespace hgl
/**
* (线)
*/
Primitive *CreateBoundingBox(PrimitiveCreater *pc,const BoundingBoxCreateInfo *cci);
Primitive *CreateBoundingBox(RenderResource *db,const VIL *vil,const BoundingBoxCreateInfo *cci);
/**
* 0,0,01()
*/
Primitive *CreateSphere(PrimitiveCreater *,const uint numberSlices);
Primitive *CreateSphere(RenderResource *db,const VIL *vil,const uint numberSlices);
/**
* ()
*/
Primitive *CreateDome(PrimitiveCreater *pc, const uint numberSlices);
Primitive *CreateDome(RenderResource *db,const VIL *vil, const uint numberSlices);
struct TorusCreateInfo
{
@ -188,7 +186,7 @@ namespace hgl
/**
* ()
*/
Primitive *CreateTorus(PrimitiveCreater *pc,const TorusCreateInfo *tci);
Primitive *CreateTorus(RenderResource *db,const VIL *vil,const TorusCreateInfo *tci);
struct CylinderCreateInfo
{
@ -200,7 +198,7 @@ namespace hgl
/**
* ()
*/
Primitive *CreateCylinder(PrimitiveCreater *,const CylinderCreateInfo *cci);
Primitive *CreateCylinder(RenderResource *db,const VIL *vil,const CylinderCreateInfo *cci);
struct ConeCreateInfo
{
@ -213,7 +211,7 @@ namespace hgl
/**
* ()
*/
Primitive *CreateCone(PrimitiveCreater *,const ConeCreateInfo *cci);
Primitive *CreateCone(RenderResource *db,const VIL *vil,const ConeCreateInfo *cci);
struct AxisCreateInfo
{
@ -234,7 +232,7 @@ namespace hgl
/**
* 线(线)
*/
Primitive *CreateAxis(PrimitiveCreater *pc,const AxisCreateInfo *aci);
Primitive *CreateAxis(RenderResource *db,const VIL *vil,const AxisCreateInfo *aci);
}//namespace inline_geometry
}//namespace graph
};//namespace hgl

View File

@ -2,7 +2,7 @@
#define HGL_GRAPH_LIGHT_INCLUDE
#include<hgl/math/Math.h>
#include<hgl/color/Color4f.h>
#include<hgl/type/Color4f.h>
namespace hgl
{
namespace graph

View File

@ -1,45 +0,0 @@
#pragma once
#include<hgl/graph/VKNamespace.h>
#include<hgl/TypeFunc.h>
VK_NAMESPACE_BEGIN
/**
*
*/
enum class LightingCullingMode
{
None, ///<不剔除
/**
*
*
*
*/
WorldCoord, ///<世界坐标剔除
/*
* Tile的剔除模式
* XY坐标划分成多个Tileznear/zfar形成一个VolumeVolume计算相交性
*/
Tile, ///<瓦片剔除
/**
* Tile的剔除模式的改进型
* Tile方法Tile后Tile内所有象素Tile的最远z值和最近z值
* XY与zNear/zFar得出一个VolumeVolume相交性
*/
TileVolume, ///<瓦片体积剔除
/**
* Tile的剔除模式的改进型
* TileVolume方法得出Volume后Volume按深度划分成多个Volume
* VolumeVolume与光源计算相交性
*/
Cluster, ///<集簇剔除
ENUM_CLASS_RANGE(None,Cluster)
};//enum class LightingCullingMode
VK_NAMESPACE_END

View File

@ -1,125 +1,75 @@
#pragma once
#include<hgl/graph/RenderNode.h>
#include<hgl/graph/VKVABList.h>
#include<hgl/graph/VKIndirectCommandBuffer.h>
#include<hgl/graph/VKVBOList.h>
VK_NAMESPACE_BEGIN
class RenderAssignBuffer;
class SceneNode;
struct CameraInfo;
struct RenderPipelineIndex:public Comparator<RenderPipelineIndex>
{
Material *material;
Pipeline *pipeline;
public:
const int compare(const RenderPipelineIndex &rli)const override
{
if(material<rli.material)return(-1);
if(material>rli.material)return(1);
if(pipeline<rli.pipeline)return(-1);
if(pipeline>rli.pipeline)return(1);
return(0);
}
public:
RenderPipelineIndex()
{
material=nullptr;
pipeline=nullptr;
}
RenderPipelineIndex(Material *m,Pipeline *p)
{
material=m;
pipeline=p;
}
};//struct RenderPipelineIndex
/**
* 线
*
*/
class MaterialRenderList
{
VulkanDevice *device;
GPUDevice *device;
RenderCmdBuffer *cmd_buf;
RenderPipelineIndex rp_index;
CameraInfo *camera_info;
Material *mtl;
RenderNodeList rn_list;
RenderNodePointerList rn_update_l2w_list;
private:
RenderAssignBuffer *assign_buffer;
struct RenderItem
{
uint32_t first_instance; ///<第一个绘制实例(和instance渲染无关,对应InstanceRate的VAB)
uint32_t instance_count;
uint32_t first;
uint32_t count;
MaterialInstance * mi;
const MeshDataBuffer * pdb;
const MeshRenderData * prd;
Pipeline * pipeline;
MaterialInstance * mi;
const VertexInputData * vid;
public:
void Set(Mesh *);
void Set(Renderable *);
};
IndirectDrawBuffer *icb_draw;
IndirectDrawIndexedBuffer *icb_draw_indexed;
void ReallocICB();
void WriteICB(VkDrawIndirectCommand *,RenderItem *ri);
void WriteICB(VkDrawIndexedIndirectCommand *,RenderItem *ri);
MaterialInstanceSets mi_set;
DataArray<RenderItem> ri_array;
uint ri_count;
void StatMI();
void Stat();
protected:
VABList * vab_list;
VBOList * vbo_list;
const MeshDataBuffer * last_data_buffer;
const VDM * last_vdm;
const MeshRenderData * last_render_data;
const VIL * last_vil;
Pipeline * last_pipeline;
const VertexInputData * last_vid;
uint last_index;
int first_indirect_draw_index;
uint indirect_draw_count;
void Bind(MaterialInstance *);
bool Bind(const VertexInputData *,const uint);
bool BindVAB(const MeshDataBuffer *,const uint);
void ProcIndirectRender();
bool Render(RenderItem *);
void Render(RenderItem *);
public:
MaterialRenderList(VulkanDevice *d,bool l2w,const RenderPipelineIndex &rpi);
MaterialRenderList(GPUDevice *d,Material *m);
~MaterialRenderList();
void Add(MeshComponent *);
void Add(Renderable *ri,const Matrix4f &mat);
void SetCameraInfo(CameraInfo *ci){camera_info=ci;}
void Clear(){rn_list.Clear();}
void Clear()
{
rn_list.Clear();
}
void End();
void Render(RenderCmdBuffer *);
void UpdateLocalToWorld(); //刷新所有对象的LocalToWorld矩阵
void UpdateMaterialInstance(MeshComponent *);
};//class MaterialRenderList
VK_NAMESPACE_END

View File

@ -2,20 +2,17 @@
#include<hgl/graph/MaterialRenderList.h>
VK_NAMESPACE_BEGIN
class MaterialRenderMap:public ObjectMap<RenderPipelineIndex,MaterialRenderList>
class MaterialRenderMap:public ObjectMap<Material *,MaterialRenderList>
{
public:
MaterialRenderMap()=default;
virtual ~MaterialRenderMap()=default;
void Begin(CameraInfo *ci)
void Begin()
{
for(auto *it:data_list)
{
it->value->SetCameraInfo(ci);
it->value->Clear();
}
}
void End()
@ -31,11 +28,5 @@ public:
for(auto *it:data_list)
it->value->Render(rcb);
}
void UpdateLocalToWorld()
{
for(auto *it:data_list)
it->value->UpdateLocalToWorld();
}
};//class MaterialRenderMap
VK_NAMESPACE_END

View File

@ -1,120 +0,0 @@
#pragma once
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/VKPipeline.h>
#include<hgl/graph/VKDescriptorSet.h>
#include<hgl/graph/VKMaterial.h>
#include<hgl/graph/VKMaterialParameters.h>
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VertexAttrib.h>
VK_NAMESPACE_BEGIN
/**
* <Br>
*
*/
struct MeshDataBuffer:public Comparator<MeshDataBuffer>
{
uint32_t vab_count;
VkBuffer * vab_list;
// 理论上讲每个VAB绑定时都是可以指定byte offsets的。但是随后Draw时又可以指定vertexOffset。
// 在我们支持的两种draw模式中一种是每个模型一批VAB所有VAB的offset都是0。
// 另一种是使用VDM为了批量渲染所有的VAB又必须对齐所以每个VAB单独指定offset也不可行。
VkDeviceSize * vab_offset; //注意这里的offset是字节偏移不是顶点偏移
IndexBuffer * ibo;
VertexDataManager *vdm; //只是用来区分和比较的,不实际使用
public:
MeshDataBuffer(const uint32_t,IndexBuffer *,VertexDataManager *_v=nullptr);
~MeshDataBuffer();
const int compare(const MeshDataBuffer &pdb)const override;
};//struct MeshDataBuffer
/**
* <Br>
*
*/
struct MeshRenderData:public ComparatorData<MeshRenderData>
{
//因为要VAB是流式访问所以我们这个结构会被用做排序依据
//也因此把vertex_offset放在最前面
int32_t vertex_offset; //注意这里的offset是相对于vertex的代表第几个顶点不是字节偏移
uint32_t first_index;
uint32_t vertex_count;
uint32_t index_count;
public:
MeshRenderData(const uint32_t vc,const uint32_t ic,const int32_t vo=0,const uint32_t fi=0)
{
vertex_count =vc;
index_count =ic;
vertex_offset =vo;
first_index =fi;
}
};
/**
* ()
*/
class Mesh
{
Pipeline * pipeline;
MaterialInstance * mat_inst;
Primitive * primitive;
MeshDataBuffer * data_buffer;
MeshRenderData * render_data;
private:
friend Mesh *CreateMesh(Primitive *,MaterialInstance *,Pipeline *);
Mesh(Primitive *,MaterialInstance *,Pipeline *,MeshDataBuffer *,MeshRenderData *);
public:
virtual ~Mesh()
{
//需要在这里添加删除pipeline/desc_sets/primitive引用计数的代码
SAFE_CLEAR(data_buffer);
SAFE_CLEAR(render_data);
}
void UpdatePipeline (Pipeline *p){pipeline=p;}
Pipeline * GetPipeline (){return pipeline;}
VkPipelineLayout GetPipelineLayout (){return mat_inst->GetMaterial()->GetPipelineLayout();}
Material * GetMaterial (){return mat_inst->GetMaterial();}
MaterialInstance * GetMaterialInstance (){return mat_inst;}
Primitive * GetPrimitive (){return primitive;}
const AABB & GetBoundingBox ()const{return primitive->GetBoundingBox();}
const MeshDataBuffer * GetDataBuffer ()const{return data_buffer;}
const MeshRenderData * GetRenderData ()const{return render_data;}
public:
bool ChangeMaterialInstance(MaterialInstance *mi)
{
if(!mi)
return(false);
if(mi->GetMaterial()!=mat_inst->GetMaterial()) //不能换母材质
return(false);
mat_inst=mi;
return(true);
}
};//class Mesh
Mesh *CreateMesh(Primitive *,MaterialInstance *,Pipeline *);
VK_NAMESPACE_END

View File

@ -1,81 +1,85 @@
#pragma once
#ifndef HGL_GRAPH_PRIMITIVE_CREATER_INCLUDE
#define HGL_GRAPH_PRIMITIVE_CREATER_INCLUDE
#include<hgl/graph/VKBufferMap.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/VertexAttribDataAccess.h>
#include<hgl/graph/VKShaderModule.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/VKIndexBuffer.h>
VK_NAMESPACE_BEGIN
/**
*
*/
class PrimitiveCreater
namespace hgl
{
protected:
namespace graph
{
/**
*
*/
class PrimitiveCreater
{
struct PrimitiveVertexBuffer
{
AnsiString name;
uint binding;
VAD * data =nullptr;
VBO * vbo =nullptr;
VulkanDevice * device;
VertexDataManager * vdm;
public:
const VIL * vil;
~PrimitiveVertexBuffer()
{
SAFE_CLEAR(data);
}
};//struct PrimitiveVertexBuffer
protected:
using PVBMap=ObjectMap<AnsiString,PrimitiveVertexBuffer>;
AnsiString prim_name;
PrimitiveData * prim_data;
protected:
uint32_t vertices_number; ///<顶点数量
RenderResource *db;
Material *mtl;
bool has_index; ///<是否有索引
uint32_t index_number; ///<索引数量
IndexType index_type; ///<索引类型
IndexBuffer * ibo; ///<索引缓冲区
const VIL *vil;
protected:
const int InitVAB(const AnsiString &name,const VkFormat format,const void *data); ///<取得顶点属性索引
protected:
public:
uint32 vertices_number;
PrimitiveCreater(VulkanDevice *,const VIL *);
PrimitiveCreater(VertexDataManager *);
virtual ~PrimitiveCreater();
IndexBuffer * ibo;
PVBMap vbo_map;
/**
*
* @parama name
* @parama vertices_count
* @parama index_count
* @parama it (使VDM时)
*/
bool Init(const AnsiString &name,
const uint32_t vertices_count,
const uint32_t index_count=0,IndexType it=IndexType::AUTO);
public:
void Clear(); ///<清除创建器数据
PrimitiveCreater(RenderResource *sdb,const VIL *);
virtual ~PrimitiveCreater()=default;
public: //顶点缓冲区
virtual bool Init(const uint32 vertices_count); ///<初始化,参数为顶点数量
const uint32_t GetVertexCount()const{ return vertices_number; } ///<取得顶点数量
VAD * CreateVAD(const AnsiString &name); ///<创建一个顶点属性缓冲区
VABMap * GetVABMap (const AnsiString &name,const VkFormat format=VK_FORMAT_UNDEFINED);
template<typename T>
T * AccessVAD(const AnsiString &name) ///<创建一个顶点属性缓冲区以及访问器
{
const VkFormat format=vil->GetVulkanFormat(name);
bool WriteVAB (const AnsiString &name,const VkFormat format,const void *data); ///<直接写入顶点属性数据
if(format!=T::GetVulkanFormat())
return(nullptr);
public: //索引缓冲区
VAD *vad=this->CreateVAD(name);
const bool hasIndex()const{return vdm?has_index:index_number>0;} ///<是否有索引缓冲区
const IndexType GetIndexType()const{return index_type;} ///<取得索引类型
const uint32_t GetIndexCount()const{return index_number;} ///<取得索引数量
if(!vad)
return(nullptr);
IBMap * GetIBMap();
T *access=T::Create(vad);
bool WriteIBO(const void *data,const uint32_t count);
access->Begin();
template<typename T>
bool WriteIBO(const T *data){return WriteIBO(data,index_number);}
return access;
}
public: //创建可渲染对象
bool WriteVAD(const AnsiString &name,const void *data,const uint32_t bytes); ///<直接写入顶点属性数据
Primitive * Create(); ///<创建一个可渲染对象,并清除创建器数据
};//class PrimitiveCreater
VK_NAMESPACE_END
uint16 * CreateIBO16(uint count,const uint16 *data=nullptr); ///<创建16位的索引缓冲区
uint32 * CreateIBO32(uint count,const uint32 *data=nullptr); ///<创建32位的索引缓冲区
virtual Primitive * Finish(); ///<结束并创建可渲染对象
};//class PrimitiveCreater
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_PRIMITIVE_CREATER_INCLUDE

View File

@ -1,273 +0,0 @@
#pragma once
#include<hgl/platform/Window.h>
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/module/SwapchainModule.h>
#include<hgl/graph/module/GraphModuleManager.h>
#include<hgl/graph/RenderList.h>
#include<hgl/graph/CameraControl.h>
#include<hgl/graph/Renderer.h>
#include<hgl/graph/VKRenderResource.h>
#include<hgl/graph/mtl/MaterialLibrary.h>
#include<hgl/io/event/MouseEvent.h>
VK_NAMESPACE_BEGIN
class FontSource;
class TileFont;
class RenderPassManager;
class TextureManager;
class RenderTargetManager;
class RenderModule;
class Scene;
class Renderer;
class CameraComponentManager{/*现阶段测试使用*/};
class LightComponentManager{/*现阶段测试使用*/};
class RenderFramework:public io::WindowEvent
{
OSString app_name;
Window * win =nullptr;
VulkanInstance * inst =nullptr;
VulkanDevice * device =nullptr;
RenderResource * render_resource =nullptr;
protected:
GraphModuleManager * module_manager =nullptr;
RenderPassManager * rp_manager =nullptr;
TextureManager * tex_manager =nullptr;
RenderTargetManager * rt_manager =nullptr;
SwapchainModule * sc_module =nullptr;
protected:
CameraComponentManager *camera_component_manager=nullptr;
LightComponentManager *light_component_manager =nullptr;
protected: //RenderContext,未来合并成一个RenderContext结构
Scene * default_scene =nullptr;
Camera * default_camera =nullptr;
CameraControl * default_camera_control =nullptr;
Renderer * default_renderer =nullptr;
void CreateDefaultRenderer();
protected: //InputEvent
io::MouseEvent *mouse_event=nullptr;
public:
Window * GetWindow ()const{return win;}
VulkanDevice * GetDevice ()const{return device;}
VkDevice GetVkDevice ()const{return device->GetDevice();}
const VulkanPhyDevice * GetPhyDevice ()const{return device->GetPhyDevice();}
VulkanDevAttr * GetDevAttr ()const{return device->GetDevAttr();}
RenderResource * GetRenderResource ()const{return render_resource;}
public:
GraphModuleManager * GetModuleManager (){return module_manager;}
RenderPassManager * GetRenderPassManager (){return rp_manager;}
TextureManager * GetTextureManager (){return tex_manager;}
RenderTargetManager * GetRenderTargetManager (){return rt_manager;}
SwapchainModule * GetSwapchainModule (){return sc_module;}
SwapchainRenderTarget * GetSwapchainRenderTarget(){return sc_module?sc_module->GetRenderTarget():nullptr;}
public:
Scene * GetDefaultScene (){return default_scene;}
Camera * GetDefaultCamera (){return default_camera;}
CameraControl * GetDefaultCameraControl (){return default_camera_control;}
Renderer * GetDefaultRenderer (){return default_renderer;}
RenderPass * GetDefaultRenderPass (){return default_renderer->GetRenderPass();}
public:
bool GetMouseCoord(Vector2i *mc)const
{
if(!mouse_event||!mc)
return(false);
*mc=mouse_event->GetMouseCoord();
return(true);
}
public:
RenderFramework(const OSString &);
virtual ~RenderFramework();
virtual bool Init(uint w,uint h);
public: // event
virtual void OnResize(uint w,uint h);
virtual void OnActive(bool);
virtual void OnClose();
public:
void Tick();
public: // other
RenderList *CreateRenderList()
{
return(new RenderList(device));
}
TileFont *CreateTileFont(FontSource *fs,int limit_count=-1); ///<创建只使用一种字符的Tile字符管理对象
public:
template<typename ...ARGS>
graph::Pipeline *CreatePipeline(ARGS...args)
{
return GetDefaultRenderPass()->CreatePipeline(args...);
}
graph::MaterialInstance *CreateMaterialInstance(const AnsiString &mi_name,const graph::mtl::MaterialCreateInfo *mci,const graph::VILConfig *vil_cfg=nullptr)
{
return render_resource->CreateMaterialInstance(mi_name,mci,vil_cfg);
}
graph::MaterialInstance *CreateMaterialInstance(const AnsiString &mtl_name,graph::mtl::MaterialCreateConfig *mtl_cfg,const graph::VILConfig *vil_cfg=nullptr)
{
AutoDelete<graph::mtl::MaterialCreateInfo> mci=graph::mtl::CreateMaterialCreateInfo(GetDevAttr(),mtl_name,mtl_cfg);
return render_resource->CreateMaterialInstance(mtl_name,mci,vil_cfg);
}
SharedPtr<graph::PrimitiveCreater> GetPrimitiveCreater(graph::Material *mtl)
{
if(!mtl)
return(nullptr);
return(new graph::PrimitiveCreater(GetDevice(),mtl->GetDefaultVIL()));
}
SharedPtr<graph::PrimitiveCreater> GetPrimitiveCreater(graph::MaterialInstance *mi)
{
if(!mi)
return(nullptr);
return(new graph::PrimitiveCreater(GetDevice(),mi->GetVIL()));
}
public: // Primitive, Mesh
graph::Primitive *CreatePrimitive(const AnsiString &name,
const uint32_t vertices_count,
const graph::VIL *vil,
const std::initializer_list<graph::VertexAttribDataPtr> &vad_list);
graph::Mesh *CreateMesh(const AnsiString &name,
const uint32_t vertices_count,
graph::MaterialInstance *mi,
graph::Pipeline *pipeline,
const std::initializer_list<graph::VertexAttribDataPtr> &vad_list);
public: // ComponentManager
template<typename T> T *GetComponentManager()
{
return COMPONENT_NAMESPACE::GetComponentManager<T>(true);
}
template<> CameraComponentManager *GetComponentManager<CameraComponentManager>()
{
return camera_component_manager;
}
template<> LightComponentManager *GetComponentManager<LightComponentManager>()
{
return light_component_manager;
}
public: //Component 相关
template<typename C,typename ...ARGS>
inline C *CreateComponent(ARGS...args)
{
auto manager=C::GetDefaultManager(); //取得默认管理器
if(!manager)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, no default manager!"));
return(nullptr);
}
return manager->CreateComponent(args...); //创建组件
}
template<typename C,typename ...ARGS>
inline C *CreateComponent(graph::SceneNode *parent_node,ARGS...args)
{
if(!parent_node)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, parent node is null!"));
return(nullptr);
}
C *c=this->CreateComponent<C>(args...); //创建组件
if(!c)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, create component failed!"));
return(nullptr);
}
/**
* Component头文件
*/
parent_node->AttachComponent(c); //将组件附加到父节点
return c;
}
template<typename C,typename ...ARGS>
inline C *CreateComponent(const graph::Matrix4f &mat,graph::SceneNode *parent_node,ARGS...args)
{
if(!parent_node)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, parent node is null!"));
return(nullptr);
}
C *c=this->CreateComponent<C>(args...); //创建组件
if(!c)
{
// LOG_ERROR(OS_TEXT("CreateComponent failed, create component failed!"));
return(nullptr);
}
/**
* Component头文件
*/
parent_node->AttachComponent(c); //将组件附加到父节点
c->graph::SceneOrient::SetLocalMatrix(mat);
return c;
}
};//class RenderFramework
VK_NAMESPACE_END

Some files were not shown because too many files have changed in this diff Show More