Compare commits

..

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

1326 changed files with 6784 additions and 201466 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 416e96c16923dede9dba5a483e1fe239116e8679

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

@ -1 +1 @@
Subproject commit 74e33b497274e51c35a5ee19a274b12dc86deecb
Subproject commit 2c10960ec30766ccafb2612e81cb88a89307c633

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,5 +1,4 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
@ -11,8 +10,7 @@
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)
CreateProject(01_draw_triangle_in_NDC draw_triangle_in_NDC.cpp)
CreateProject(02_draw_triangle_use_UBO draw_triangle_use_UBO.cpp)
CreateProject(03_auto_instance auto_instance.cpp)
CreateProject(04_auto_merge_material_instance auto_merge_material_instance.cpp)

View File

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

View File

@ -1,18 +1,20 @@
// 该范例主要演示使用RenderList系统绘制多个三角形并利用RenderList进行排序以及自动合并进行Instance渲染
#include<hgl/WorkManager.h>
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/component/MeshComponent.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t VERTEX_COUNT=3;
constexpr uint32_t SCREEN_WIDTH=1024;
constexpr uint32_t SCREEN_HEIGHT=1024;
constexpr uint32_t TRIANGLE_NUMBER=12;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT*2]=
{
@ -22,18 +24,20 @@ constexpr float position_data[VERTEX_COUNT*2]=
};
constexpr uint8 color_data[VERTEX_COUNT][4]=
{
{255,0,0,255},
{ {255,0,0,255},
{0,255,0,255},
{0,0,255,255}
};
class TestApp:public WorkObject
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
@ -42,60 +46,64 @@ private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,
CoordinateSystem2D::NDC,
mtl::WithLocalToWorld::With);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D",Prim::Triangles);
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=CreateMaterialInstance(mtl::inline_material::VertexColor2D,&cfg,&vil_config);
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); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为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 }
});
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);
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));
for(uint i=0;i<12;i++)
render_root.CreateSubNode(rotate(deg2rad(30*i),Vector3f(0,0,1)),render_obj);
CreateComponent<MeshComponent>(mat,scene_root,render_obj);
}
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
using WorkObject::WorkObject;
bool Init() override
~TestApp()
{
GetRenderer()->SetClearColor(Color4f(0.2f,0.2f,0.2f,1.0f));
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMaterial())
return(false);
@ -103,11 +111,27 @@ public:
if(!InitVBO())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
return RunFramework<TestApp>(OS_TEXT("AutoInstance"),1024,1024);
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -1,15 +1,19 @@
// 该范例主要演示使用一个材质下的不同材质实例传递颜色参数绘制三角形并依赖RenderList中的自动合并功能让同一材质下所有不同材质实例的对象一次渲染完成。
#include<hgl/WorkManager.h>
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
#include<hgl/color/Color.h>
#include<hgl/component/MeshComponent.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]=
@ -20,18 +24,20 @@ constexpr float position_data[VERTEX_COUNT*2]=
};
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
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Material * material =nullptr;
struct
{
MaterialInstance * mi;
Mesh * mesh;
Renderable * r;
}render_obj[DRAW_OBJECT_COUNT]{};
Pipeline * pipeline =nullptr;
@ -41,14 +47,14 @@ private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,CoordinateSystem2D::NDC,mtl::WithLocalToWorld::With);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureColor2D",Prim::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=true;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureColor2D(&cfg);
#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);
@ -66,57 +72,75 @@ private:
}
}
pipeline=CreatePipeline(material,InlinePipeline::Solid2D);
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Triangles);
return pipeline;
}
bool InitVBOAndRenderList()
{
Primitive *prim=CreatePrimitive("Triangle",VERTEX_COUNT,material->GetDefaultVIL(),
{{VAN::Position, VF_V2F, position_data}});
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
if(!prim)
return(false);
db->Add(prim);
Matrix4f mat;
SceneNode *scene_root=GetSceneRoot(); ///<取得场景根节点
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].mesh=db->CreateMesh(prim,render_obj[i].mi,pipeline);
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
if(!render_obj[i].mesh)
if(!render_obj[i].r)
return(false);
mat=rotate(deg2rad<double>(TRI_ROTATE_ANGLE*i),AxisVector::Z);
CreateComponent<MeshComponent>(mat,scene_root,render_obj[i].mesh);
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:
using WorkObject::WorkObject;
bool Init() override
~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(!InitVBOAndRenderList())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
return RunFramework<TestApp>(OS_TEXT("AutoInstance"),1024,1024);
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -0,0 +1,166 @@
// 该范例主要演示使用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",Prim::Triangles);
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

@ -1,44 +1,42 @@
// 该范例主要演示使用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>
#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_float[VERTEX_COUNT][2]=
static float position_data[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]=
constexpr float color_data[VERTEX_COUNT][4]=
{
255,0,0,255,
0,255,0,255,
0,0,255,255
{1,0,0,1},
{0,1,0,1},
{0,0,1,1}
};
constexpr VAType POSITION_SHADER_FORMAT =VAT_IVEC2;
constexpr VkFormat POSITION_DATA_FORMAT =VF_V2I16;
//#define USE_ZERO2ONE_COORD //使用左上角0,0右下角1,1的坐标系
constexpr VkFormat COLOR_DATA_FORMAT =VF_V4UN8;
class TestApp:public WorkObject
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Mesh * mesh_triangle =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
@ -46,70 +44,87 @@ private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(PrimitiveType::Triangles,
CoordinateSystem2D::Ortho,
mtl::WithLocalToWorld::With);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D",Prim::Triangles);
VILConfig vil_config;
#ifdef USE_ZERO2ONE_COORD
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
#else
cfg.coordinate_system=CoordinateSystem2D::Ortho;
#endif//USE_ZERO2ONE_COORD
cfg.position_format = POSITION_SHADER_FORMAT; //这里指定shader中使用ivec2当做顶点输入格式
// ^
// + 这上下两种格式要配套,否则会出错
// v
vil_config.Add(VAN::Position, POSITION_DATA_FORMAT); //这里指定VAB中使用RG16I当做顶点数据格式
cfg.local_to_world=false;
vil_config.Add(VAN::Color, COLOR_DATA_FORMAT); //这里指定VAB中使用RGBA8UNorm当做颜色数据格式
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateVertexColor2D(&cfg);
material_instance=CreateMaterialInstance(mtl::inline_material::VertexColor2D,&cfg,&vil_config);
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); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
const auto ext=GetExtent();
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
#ifndef USE_ZERO2ONE_COORD //使用ortho坐标系
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;
position_data[i][0]*=SCREEN_WIDTH;
position_data[i][1]*=SCREEN_HEIGHT;
}
mesh_triangle=CreateMesh("Triangle",VERTEX_COUNT,material_instance,pipeline,
{
{VAN::Position,POSITION_DATA_FORMAT,position_data},
{VAN::Color, COLOR_DATA_FORMAT, color_data}
});
#endif//USE_ZERO2ONE_COORD
if(!mesh_triangle)
return(false);
return CreateComponent<MeshComponent>(GetSceneRoot(),mesh_triangle); //创建一个静态网格组件
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:
using WorkObject::WorkObject;
bool Init() override
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);
}
};//class TestApp:public WorkObject
int os_main(int,os_char **)
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
return RunFramework<TestApp>(OS_TEXT("Draw triangle use UBO"));
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@ -1,10 +1,9 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/common)
SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h)
SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h)
add_subdirectory(Basic)
add_subdirectory(Texture)
add_subdirectory(LightBasic)
add_subdirectory(Gizmo)
add_subdirectory(Vulkan)
@ -22,3 +21,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

@ -10,15 +10,4 @@
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
)
CreateProject(PlaneGrid3D PlaneGrid3D.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 +1,160 @@
// PlaneGrid3D
// 4.Geometry3D
#include<hgl/WorkManager.h>
#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/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
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 * prim_plane_grid =nullptr;
MaterialInstance * material_instance[3]{};
Primitive * ro_plane_grid[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);
material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D"));
if(!material)return(false);
VILConfig vil_config;
material_instance=db->CreateMaterialInstance(material);
if(!material_instance)return(false);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines);
if(!pipeline)
return(false);
vil_config.Add(VAN::Luminance,VF_V1UN8);
return(true);
}
Renderable *Add(Primitive *r,const Matrix4f &mat)
{
Renderable *ri=db->CreateRenderable(r,material_instance,pipeline);
Color4f GridColor;
COLOR ce=COLOR::BlenderAxisRed;
render_root.CreateSubNode(mat,ri);
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;
return ri;
}
bool CreateRenderObject()
void CreateRenderObject()
{
using namespace inline_geometry;
struct PlaneGridCreateInfo pgci;
pgci.grid_size.Set(32,32);
pgci.sub_count.Set(8,8);
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.lum=180;
pgci.sub_lum=255;
pgci.step.x=32;
pgci.step.y=32;
auto pc=GetPrimitiveCreater(material_instance[0]);
pgci.side_step.x=8;
pgci.side_step.y=8;
prim_plane_grid=CreatePlaneGrid2D(pc,&pgci);
pgci.color.Set(0.5,0,0,1);
pgci.side_color.Set(1,0,0,1);
return prim_plane_grid;
}
const VIL *vil=material_instance->GetVIL();
void Add(SceneNode *parent_node,MaterialInstance *mi,const Matrix4f &mat)
{
Mesh *ri=db->CreateMesh(prim_plane_grid,mi,pipeline);
ro_plane_grid[0]=CreatePlaneGrid(db,vil,&pgci);
if(!ri)
return;
pgci.color.Set(0,0.5,0,1);
pgci.side_color.Set(0,1,0,1);
CreateComponent<MeshComponent>(mat,parent_node,ri);
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()
{
SceneNode *scene_root=GetSceneRoot(); //取得缺省场景根节点
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));
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->pos=Vector3f(200,200,200);
camera_control->SetTarget(Vector3f(0,0,0));
camera_control->Refresh();
// camera_control->SetReserveDirection(true,true); //反转x,y
render_root.RefreshMatrix();
render_list->Expend(camera->info,&render_root);
return(true);
}
public:
using WorkObject::WorkObject;
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
SAFE_CLEAR(render_list);
}
bool Init() override
bool Init()
{
if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitMDP())
return(false);
if(!CreateRenderObject())
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 os_main(int,os_char **)
int main(int,char **)
{
return RunFramework<TestApp>(OS_TEXT("PlaneGrid3D"),1280,720);
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

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

@ -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

@ -4,15 +4,15 @@
#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/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/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;
@ -44,25 +44,27 @@ private:
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"PureTexture2D",PrimitiveType::Fan);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureTexture2D",Prim::Fan);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
material=db->LoadMaterial("Std2D/PureTexture2D",&cfg);
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureTexture2D(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
// 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,InlinePipeline::Solid2D,Prim::Fan); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -73,7 +75,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@ -85,14 +87,12 @@ private:
bool InitVBO()
{
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Quad",VERTEX_COUNT);
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
if(!rpc.WriteVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
render_obj=db->CreateMesh(&rpc,material_instance,pipeline);
render_obj=rpc.Create(material_instance,pipeline);
return(render_obj);
}
@ -114,7 +114,7 @@ public:
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);

View File

@ -4,15 +4,15 @@
#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/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/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;
@ -40,25 +40,27 @@ private:
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Mesh * render_obj =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"RectTexture2D",PrimitiveType::SolidRectangles);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"RectTexture2D",Prim::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=false;
material=db->LoadMaterial("Std2D/RectTexture2D",&cfg);
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateRectTexture2D(&cfg);
material=db->CreateMaterial(mci);
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
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -69,7 +71,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@ -81,14 +83,12 @@ private:
bool InitVBO()
{
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Rectangle",1);
RenderablePrimitiveCreater rpc(db,1);
if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
if(!rpc.SetVBO(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
render_obj=db->CreateMesh(&rpc,material_instance,pipeline);
render_obj=rpc.Create(material_instance,pipeline);
return(render_obj);
}
@ -110,7 +110,7 @@ public:
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);

View File

@ -4,8 +4,8 @@
#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/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
#include<hgl/filesystem/Filename.h>
@ -13,7 +13,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=256;
@ -56,20 +56,18 @@ private:
Pipeline * pipeline =nullptr;
DeviceBuffer * tex_id_ubo =nullptr;
Primitive * prim_rectangle =nullptr;
struct
{
MaterialInstance * mi;
Mesh * mesh;
Renderable * r;
}render_obj[TexCount]{};
private:
bool InitTexture()
{
texture=db->CreateTexture2DArray( "freepik icons",
512,512, ///<纹理尺寸
texture=db->CreateTexture2DArray( 512,512, ///<纹理尺寸
TexCount, ///<纹理层数
PF_BC1_RGBAUN, ///<纹理格式
false); ///<是否自动产生mipmaps
@ -91,17 +89,19 @@ private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"RectTexture2DArray",PrimitiveType::SolidRectangles);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"RectTexture2DArray",Prim::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=true;
material=db->LoadMaterial("Std2D/RectTexture2DArray",&cfg);
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateRectTexture2DArray(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,PrimitiveType::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@ -109,7 +109,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@ -129,29 +129,25 @@ private:
bool InitVBOAndRenderList()
{
PrimitiveCreater rpc(device,material->GetDefaultVIL());
rpc.Init("Rectangle",1);
RenderablePrimitiveCreater rpc(db,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();
if(!rpc.SetVBO(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
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);
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
if(!render_obj[i].mesh)
if(!render_obj[i].r)
return(false);
offset.x=position_data[2]*float(i);
render_root.CreateSubNode(translate(offset),render_obj[i].mesh);
render_root.CreateSubNode(translate(offset),render_obj[i].r);
}
render_root.RefreshMatrix();
@ -165,7 +161,6 @@ public:
~TestApp()
{
SAFE_CLEAR(prim_rectangle);
SAFE_CLEAR(render_list);
}
@ -190,7 +185,7 @@ public:
return(true);
}
void Resize(uint w,uint h)override
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);

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

@ -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

@ -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,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

@ -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(Material *mtl)
{
return mtl->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,7 +20,7 @@ namespace hgl
Bitmap2DLoader():Texture2DLoader(){}
~Bitmap2DLoader();
void *OnBegin(uint32 total_bytes,const VkFormat &) override;
void *OnBegin(uint32 total_bytes) override;
bool OnEnd() override {return(false);}
BitmapData *GetBitmap();

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

View File

@ -18,9 +18,7 @@ namespace hgl
{
protected:
VulkanDevice * device;
CameraInfo * camera_info; ///<相机信息
GPUDevice * device;
uint renderable_count; ///<可渲染对象数量
MaterialRenderMap mrl_map; ///<按材质分类的渲染列表
@ -31,24 +29,14 @@ namespace hgl
public:
const CameraInfo *GetCameraInfo()const{return camera_info;}
public:
RenderList(VulkanDevice *);
virtual ~RenderList()=default;
RenderList(GPUDevice *);
virtual ~RenderList();
virtual void SetCameraInfo(CameraInfo *ci){camera_info=ci;} ///<设置相机信息
virtual bool Expend(SceneNode *); ///<展开场景树到渲染列表
virtual bool Expend(SceneNode *); ///<展开场景树到渲染列表
bool IsEmpty()const{return !renderable_count;} ///<是否是空的
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
virtual bool Render(RenderCmdBuffer *); ///<渲染所有对象
virtual void UpdateLocalToWorld(); ///<更新所有对象的变换数据
virtual void UpdateMaterialInstance(MeshComponent *); ///<有对象互换了材质实例
virtual void Clear(); ///<彻底清理
virtual void Clear(); ///<彻底清理
};//class RenderList
}//namespace graph
}//namespace hgl

View File

@ -1,47 +1,29 @@
#pragma once
#ifndef HGL_GRAPH_RENDER_NODE_INCLUDE
#define HGL_GRAPH_RENDER_NODE_INCLUDE
#include<hgl/graph/VK.h>
#include<hgl/type/SortedSet.h>
#include<hgl/type/SortedSets.h>
namespace hgl
{
namespace graph
{
class Mesh;
class Renderable;
class Material;
class MaterialInstance;
class MeshComponent;
class GPUDevice;
struct VertexInputData;
struct IndexBufferData;
struct RenderNode:public Comparator<RenderNode>
struct RenderNode
{
uint index; ///<在MaterialRenderList中的索引
Matrix4f local_to_world;
MeshComponent *sm_component; ///<静态网格组件
uint32 l2w_version;
uint32 l2w_index;
Vector3f world_position;
float to_camera_distance;
public:
//该函数位于MaterialRenderList.cpp
const int compare(const RenderNode &)const override;
public:
Mesh *GetMesh()const;
MaterialInstance *GetMaterialInstance()const;
Renderable *ri;
};
using RenderNodeList=ArrayList<RenderNode>;
using RenderNodePointerList=ArrayList<RenderNode *>;
using RenderNodeList=List<RenderNode>;
using MaterialInstanceSets=SortedSet<MaterialInstance *>; ///<材质实例集合
using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合
}//namespace graph
template<> inline const int ItemComparator<graph::RenderNode>::compare(const graph::RenderNode &a,const graph::RenderNode &b)
{
return a.compare(b);
}
}//namespace hgl
#endif//HGL_GRAPH_RENDER_NODE_INCLUDE

View File

@ -1,44 +0,0 @@
#pragma once
#include<hgl/graph/VK.h>
#include<hgl/type/IDName.h>
namespace hgl::graph
{
HGL_DEFINE_IDNAME(RenderTaskName,char)
/**
*
*/
class RenderTask
{
RenderTaskName task_name;
IRenderTarget * render_target;
RenderList * render_list;
CameraInfo * camera_info;
public:
const RenderTaskName &GetName ()const;
IRenderTarget * GetRenderTarget ()const{return render_target;}
RenderList * GetRenderList ()const{return render_list;}
CameraInfo * GetCameraInfo ()const{return camera_info;}
public:
RenderTask(const RenderTaskName &tn,IRenderTarget *rt=nullptr,CameraInfo *ci=nullptr);
virtual ~RenderTask();
bool SetRenderTarget(IRenderTarget *);
void SetCameraInfo(CameraInfo *);
bool RebuildRenderList(SceneNode *);
bool IsEmpty()const; ///<是否是空的,不可渲染或是没啥可渲染的
bool Render(RenderCmdBuffer *);
};//class RenderTask
}//namespace hgl::graph

View File

@ -1,57 +0,0 @@
#pragma once
#include<hgl/graph/RenderTask.h>
#include<hgl/graph/VKRenderTarget.h>
#include<hgl/graph/CameraControl.h>
#include<hgl/type/Map.h>
namespace hgl::graph
{
class Scene;
class CameraControl;
using RenderTaskNameMap=Map<RenderTaskName,RenderTask *>;
/**
*
*/
class Renderer
{
IRenderTarget *render_target;
Scene *scene;
CameraControl *camera_control;
//RenderTaskNameMap static_render_task_list; ///<静态渲染任务列表
//RenderTaskNameMap dynamic_render_task_list; ///<动态渲染任务列表
RenderTask *render_task; ///<当前渲染任务
Color4f clear_color; ///<清屏颜色
bool build_frame=false;
public:
RenderPass *GetRenderPass (){return render_target->GetRenderPass();} ///<取得当前渲染器RenderPass
const VkExtent2D &GetExtent ()const{return render_target->GetExtent();} ///<取得当前渲染器画面尺寸
Scene * GetScene ()const{return scene;} ///<获取场景世界
Camera * GetCamera ()const{return camera_control->GetCamera();} ///<获取当前相机
public:
Renderer(IRenderTarget *);
virtual ~Renderer();
bool SetRenderTarget(IRenderTarget *);
void SetScene(Scene *);
void SetCameraControl(CameraControl *);
void SetClearColor(const Color4f &c){clear_color=c;}
bool RenderFrame(); ///<重新重成这一帧的CommandList
bool Submit(); ///<提交CommandList到GPU
};//class Renderer
}//namespace hgl::graph

View File

@ -1,50 +0,0 @@
#pragma once
#include<hgl/graph/SceneNode.h>
#include<hgl/type/Pool.h>
namespace hgl::graph
{
/**
* <Br>
*
*/
class Scene
{
U8String SceneName; ///<场景名称
ObjectList<SceneNode> SceneNodePool; ///<场景节点池
SceneNode *root_node; ///<场景根节点
public:
const U8String & GetSceneName()const{return SceneName;} ///<获取场景名称
SceneNode * GetRootNode (){return root_node;} ///<获取场景根节点
public:
Scene()
{
root_node=new SceneNode;
}
virtual ~Scene()
{
SAFE_CLEAR(root_node);
}
};//class Scene
bool RegistryScene(Scene *sw); ///<注册场景
bool UnregistryScene(const U8String &scene_name); ///<注销场景
inline bool UnregistryScene(Scene *sw) ///<注销场景
{
if(!sw)return(false);
return UnregistryScene(sw->GetSceneName());
}
Scene *GetScene(const U8String &scene_name); ///<获取指定名称的场景
}//namespace hgl::graph

38
inc/hgl/graph/SceneInfo.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef HGL_GRAPH_SCENE_INFO_INCLUDE
#define HGL_GRAPH_SCENE_INFO_INCLUDE
#include<hgl/math/Matrix.h>
#include<hgl/CompOperator.h>
namespace hgl
{
namespace graph
{
/**
* MVP矩阵
*/
struct MVPMatrix
{
Matrix4f model; ///< model: Local to World
//Matrix4f normal; ///<transpose(inverse(mat3(model)));
Matrix3x4f normal; ///<这里用3x4在Shader中是3x3(但实际它是3x4保存)
Matrix4f mv; ///< view * model
Matrix4f mvp; ///< projection * view * model
public:
void Set(const Matrix4f &local_to_world,const Matrix4f &view_projection,const Matrix4f &view)
{
model =local_to_world;
normal =transpose(inverse(model));
mv =view*model;
mvp =view_projection*model;
}
CompOperatorMemcmp(const MVPMatrix &);
};//struct MVPMatrix
constexpr size_t MVPMatrixBytes=sizeof(MVPMatrix);
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_SCENE_INFO_INCLUDE

View File

@ -1,116 +0,0 @@
#pragma once
#include<hgl/math/Transform.h>
namespace hgl
{
namespace graph
{
/**
* <br>
*
* 3D空间中的位置<br>
* :<br>
* <ul>
* <li>LocalMatrix </li>
* <li>LocalToWorldMatrix 使</li>
*
* <li>transform_manager 0</li>
* </ul>
*
* LocalToWorldMatrix=ParnetMatrix * LocalMatrix * TransformMatrix<br>
*/
class SceneMatrix :public VersionData<Matrix4f>
{
protected:
Matrix4f parent_matrix;
Matrix4f local_matrix;
bool local_is_identity;
Vector3f local_normal;
TransformManager transform_manager;
Matrix4f transform_matrix;
protected:
Vector3f OriginWorldPosition; //变换前世界坐标
Vector3f FinalWorldPosition; //变换后世界坐标
Vector3f OriginWorldNormal; //变换前世界法线
Vector3f FinalWorldNormal; //变换后世界法线
protected:
Matrix4f inverse_local_to_world_matrix; ///<世界到本地矩阵
Matrix4f inverse_transpose_local_to_world_matrix; ///<世界到本地矩阵的转置矩阵
void MakeNewestData(Matrix4f &local_to_world_matrix) override; ///<生成最新的数据(需要派生类重载)
public:
void Clear();
const Matrix4f &GetLocalMatrix()const{return local_matrix;} ///<取得本地矩阵
const Vector3f &GetLocalNormal()const{return local_normal;} ///<取得本地法线
const Matrix4f &GetLocalToWorldMatrix(){return GetNewestVersionData();} ///<取得本地到世界矩阵
const Matrix4f &GetInverseLocalToWorldMatrix(){UpdateNewestData();return inverse_local_to_world_matrix;} ///<取得世界到本地矩阵
const Matrix4f &GetInverseTransposeLocalToWorldMatrix() ///<取得世界到本地矩阵的转置矩阵
{
UpdateNewestData();
return inverse_transpose_local_to_world_matrix;
}
TransformManager &GetTransform(){return transform_manager;} ///<取得变换管理器
const Vector3f &GetWorldPosition()const{return FinalWorldPosition;} ///<取得世界坐标
const Vector3f &GetWorldNormal()const { return FinalWorldNormal; } ///<取得世界法线
public:
SceneMatrix():VersionData(Identity4f){Clear();}
SceneMatrix(SceneMatrix &so);
SceneMatrix(const Matrix4f &mat):VersionData(Identity4f)
{
SetLocalMatrix(mat);
UpdateVersion();
}
void SetLocalNormal(const Vector3f &normal)
{
//if(IsNearlyEqual(local_normal,normal))
if(!hgl_cmp(local_normal,normal))
return;
local_normal=normal;
UpdateVersion();
}
void SetLocalMatrix(const Matrix4f &mat)
{
//if (IsNearlyEqual(local_matrix,mat))
if(!hgl_cmp(local_matrix,mat))
return;
local_matrix=mat;
local_is_identity=IsIdentityMatrix(mat);
UpdateVersion();
}
void SetParentMatrix(const Matrix4f &pm)
{
//if (IsNearlyEqual(parent_matrix,pm))
if(!hgl_cmp(parent_matrix,pm))
return;
parent_matrix=pm;
UpdateVersion();
}
virtual void Update();
};//class SceneMatrix
}//namespace graph
}//namespace hgl

View File

@ -1,142 +1,102 @@
#pragma once
#ifndef HGL_GRAPH_SCENE_NODE_INCLUDE
#define HGL_GRAPH_SCENE_NODE_INCLUDE
#include<hgl/type/ObjectList.h>
#include<hgl/type/IDName.h>
#include<hgl/graph/SceneOrient.h>
#include<hgl/graph/VK.h>
#include<hgl/graph/AABB.h>
#include<hgl/component/Component.h>
namespace hgl::graph
namespace hgl
{
using SceneNodeID =int64;
using SceneNodeList =ObjectList<SceneNode>;
HGL_DEFINE_U16_IDNAME(SceneNodeName)
/**
* <br>
* (SceneOrient)
* (/)
*/
class SceneNode:public SceneOrient ///场景节点类
namespace graph
{
SceneNode *parent_node=nullptr; ///<上级节点
SceneNodeID node_id=-1; ///<节点ID
SceneNodeName node_name; ///<节点名称
protected:
AABB bounding_box; ///<绑定盒
AABB local_bounding_box; ///<本地坐标绑定盒
//AABB WorldBoundingBox; ///<世界坐标绑定盒
protected:
SceneNodeList child_nodes; ///<子节点
/**
* SceneNode下可能会包含多个组件SceneNode使用
* ComponentManager管理
* <br>
* (SceneOrient)
* (/)
*/
ComponentSet component_set; ///<组件合集
public:
const SceneNodeID & GetNodeID ()const { return node_id; } ///<取得节点ID
const SceneNodeName & GetNodeName ()const { return node_name; } ///<取得节点名称
const SceneNodeList & GetChildNode()const { return child_nodes; } ///<取得子节点列表
public:
SceneNode()=default;
SceneNode(const SceneNode &)=delete;
SceneNode(const SceneNode *)=delete;
SceneNode(const SceneOrient &so ):SceneOrient(so) {}
SceneNode(const Matrix4f &mat ):SceneOrient(mat) {}
public:
virtual ~SceneNode();
void Clear() override
class SceneNode:public SceneOrient ///场景节点类
{
SceneOrient::Clear();
protected:
parent_node=nullptr;
AABB BoundingBox; ///<绑定盒
AABB LocalBoundingBox; ///<本地坐标绑定盒
AABB WorldBoundingBox; ///<世界坐标绑定盒
bounding_box.SetZero();
local_bounding_box.SetZero();
Vector4f Center; ///<中心点
Vector4f LocalCenter; ///<本地坐标中心点
Vector4f WorldCenter; ///<世界坐标中心点
child_nodes.Clear();
component_set.Clear();
}
Renderable *render_obj=nullptr; ///<可渲染实例
const bool ChildNodeIsEmpty()const
{
if(child_nodes.GetCount())return(false);
public:
return(true);
}
ObjectList<SceneNode> SubNode; ///<子节点
void SetParent(SceneNode *sn) {parent_node=sn;}
SceneNode * GetParent() noexcept{return parent_node;}
const SceneNode * GetParent()const noexcept{return parent_node;}
public:
SceneNode *Add(SceneNode *sn)
{
if(!sn)
return(nullptr);
SceneNode()=default;
SceneNode( Renderable *ri ) {render_obj=ri;}
SceneNode(const Matrix4f &mat ):SceneOrient(mat) {}
SceneNode(const Matrix4f &mat, Renderable *ri ):SceneOrient(mat) {render_obj=ri;}
child_nodes.Add(sn);
sn->SetParent(this);
return sn;
}
virtual ~SceneNode()=default;
public: //坐标相关方法
void Clear()
{
SubNode.Clear();
render_obj=nullptr;
}
virtual void SetBoundingBox (const AABB &bb){bounding_box=bb;} ///<设置绑定盒
Renderable *GetRenderable(){return render_obj;}
void SetRenderable(Renderable *);
virtual void RefreshMatrix () override; ///<刷新世界变换
virtual void RefreshBoundingBox (); ///<刷新绑定盒
SceneNode *CreateSubNode()
{
SceneNode *sn=new SceneNode();
virtual const AABB & GetBoundingBox ()const{return bounding_box;} ///<取得绑定盒
virtual const AABB & GetLocalBoundingBox ()const{return local_bounding_box;} ///<取得本地坐标绑定盒
// virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒
SubNode.Add(sn);
return sn;
}
public: //组件相关方法
SceneNode *CreateSubNode(Renderable *ri)
{
SceneNode *sn=new SceneNode(ri);
bool ComponentIsEmpty ()const{return component_set.IsEmpty();} ///<是否没有组件
virtual const int64 GetComponentCount ()const{return component_set.GetCount();} ///<取得组件数量
virtual bool AttachComponent (Component *comp) ///<添加一个组件
{
if(!comp)return(false);
SubNode.Add(sn);
return sn;
}
if(component_set.Add(comp)<0)
return(false);
SceneNode *CreateSubNode(const Matrix4f &mat)
{
SceneNode *sn=new SceneNode(mat);
comp->OnAttach(this); //调用组件的OnAttach方法
return(true);
}
SubNode.Add(sn);
return sn;
}
virtual void DetachComponent (Component *comp) ///<删除一个组件
{
if (!comp)return;
SceneNode *CreateSubNode(const Matrix4f &mat,Renderable *ri)
{
SceneNode *sn=new SceneNode(mat,ri);
component_set.Delete(comp);
SubNode.Add(sn);
return sn;
}
comp->OnDetach(this); //调用组件的OnDetach方法
}
public: //坐标相关方法
bool Contains (Component *comp){return component_set.Contains(comp);} ///<是否包含指定组件
virtual void SetBoundingBox (const AABB &bb){BoundingBox=bb;} ///<设置绑定盒
bool HasComponent (const ComponentManager *); ///<是否有指定组件管理器的组件
virtual int GetComponents (ComponentList &comp_list,const ComponentManager *); ///<取得所有组件
virtual void RefreshMatrix (const Matrix4f *mat=nullptr); ///<刷新世界变换矩阵
virtual void RefreshBoundingBox (); ///<刷新绑定盒
const ComponentSet &GetComponents ()const{return component_set;}
};//class SceneNode
virtual const AABB & GetBoundingBox ()const{return BoundingBox;} ///<取得绑定盒
virtual const AABB & GetLocalBoundingBox ()const{return LocalBoundingBox;} ///<取得本地坐标绑定盒
virtual const AABB & GetWorldBoundingBox ()const{return WorldBoundingBox;} ///<取得世界坐标绑定盒
SceneNode *Duplication(SceneNode *); ///<复制一个场景节点
}//namespace hgl::graph
virtual const Vector4f & GetCenter ()const{return Center;} ///<取得中心点
virtual const Vector4f & GetLocalCenter ()const{return LocalCenter;} ///<取得本地坐标中心点
virtual const Vector4f & GetWorldCenter ()const{return WorldCenter;} ///<取得世界坐标中心点
};//class SceneNode
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_SCENE_NODE_INCLUDE

View File

@ -1,88 +0,0 @@
#pragma once
#include<hgl/type/DataType.h>
#include<hgl/graph/ShadowPolicy.h>
namespace hgl
{
namespace graph
{
#pragma pack(push,1)
/**
* <br>
*/
struct SceneNodeTransformAttributes
{
uint moveable:1; ///<可移动
uint rotatable:1; ///<可旋转
uint scalable:1; ///<可缩放
//为什么要 移动、旋转、缩放 三个分开而不是一个整体
// 一、不可移动、不可旋转、不可缩放的通常用于Lightmap等可以完全预计算的东西
// 二、物理引擎对于可缩放是独立支持的,所以缩放要分开
// 三、逻辑处理对移动一般有特别响应,但旋转不一定(也有可能只处理旋转),所以移动和旋转要分开
// 比如RTS中的激光坦克、电磁坦克由于是圆形范围攻击的所以不需要关心旋转属性只需要关心移动属性即可
// 同理,地面雷达,因为是扇形旋转扫描敌人的,所以只关心旋转
// 而士兵、坦克等单位,既需要移动,又需要旋转,但不会缩放
// 再比如风车,它不能移动,但可以旋转。但我们判断是否靠近是否看到,根本不需要关心旋转属性
};
/**
* <br>
*/
struct SceneNodeVisualAttributes
{
uint visible:1; ///<是否可见
uint render_color:1; ///<渲染颜色
uint render_normal:1; ///<渲染法线
uint render_depth:1; ///<渲染深度
uint render_at_reflect:1; ///<在反射时渲染
uint cast_shadow:1; ///<投射阴影
uint cast_static_shadow:1; ///<投射静态阴影(预计算阴影)
uint cast_dynamic_shadow:1; ///<投射动态阴影
uint receive_static_shadow:1; ///<接收静态阴影
uint receive_dynamic_shadow:1; ///<接收动态阴影
uint receive_static_light:1; ///<接收静态光照
uint receive_dynamic_light:1; ///<接收动态光照
ObjectDynamicShadowPolicy dynamic_shadow_policy:8; ///<动态阴影策略
// uint8 light_channels; ///<接收的光通道
};
constexpr const size_t SceneNodeVisualAttributesBytes=sizeof(SceneNodeVisualAttributes);
/**
* <br>
*/
struct SceneNodeCullAttribute
{
uint32 min_distance; ///<最小裁剪距离
uint32 max_distance; ///<最大裁剪距离
uint32 min_volume; ///<最小裁剪体积
uint32 max_volume; ///<最大裁剪体积
};
struct SceneNodeAttributes
{
uint editor_only:1; ///<仅编辑器中使用
uint can_tick:1; ///<可被Tick
SceneNodeTransformAttributes transform; ///<变换属性
SceneNodeVisualAttributes visual; ///<可视属性
SceneNodeCullAttribute cull; ///<裁剪属性
};
constexpr const size_t SceneNodeAttributesBytes=sizeof(SceneNodeAttributes);
#pragma pack(pop)
}//namespace graph
}//namespace hgl

View File

@ -1,49 +1,48 @@
#pragma once
#ifndef HGL_GRAPH_SCENE_ORIENT_INCLUDE
#define HGL_GRAPH_SCENE_ORIENT_INCLUDE
//#include<hgl/type/List.h>
#include<hgl/math/Math.h>
#include<hgl/graph/VK.h>
#include<hgl/graph/SceneMatrix.h>
namespace hgl::graph
//#include<hgl/graph/Transform.h>
namespace hgl
{
/**
* <br>
*/
class SceneOrient ///场景定位类
namespace graph
{
protected:
SceneMatrix scene_matrix;
public:
SceneOrient()=default;
SceneOrient(const SceneOrient &);
SceneOrient(const Matrix4f &);
virtual ~SceneOrient()=default;
virtual void Clear()
/**
*
*/
class SceneOrient ///场景定位类
{
scene_matrix.Clear();
}
protected:
void SetLocalNormal(const Vector3f &nor) {scene_matrix.SetLocalNormal(nor);} ///<设置本地法线
void SetLocalMatrix (const Matrix4f &mat){scene_matrix.SetLocalMatrix(mat);} ///<设置本地矩阵
void SetParentMatrix(const Matrix4f &mat){scene_matrix.SetParentMatrix(mat);} ///<设置上级到世界空间变换矩阵
//ObjectList<Transform> TransformList;
public:
Matrix4f LocalMatrix; ///<当前矩阵
Matrix4f LocalToWorldMatrix; ///<当前到世界矩阵
const uint32 GetLocalToWorldMatrixVersion()const {return scene_matrix.GetNewestVersion();} ///<取得版本号
Matrix4f InverseLocalMatrix; ///<反向当前矩阵
Matrix4f InverseLocalToWorldMatrix; ///<反向当前到世界矩阵
const Vector3f & GetWorldPosition() const {return scene_matrix.GetWorldPosition();} ///<取得世界坐标
const Matrix4f & GetLocalMatrix ()const {return scene_matrix.GetLocalMatrix();} ///<取得本地矩阵
public:
TransformManager & GetTransform () {return scene_matrix.GetTransform();} ///<取得变换管理器
SceneOrient();
SceneOrient(const Matrix4f &mat);
virtual ~SceneOrient()=default;
const Matrix4f & GetLocalToWorldMatrix () {return scene_matrix.GetLocalToWorldMatrix();} ///<取得本地到世界矩阵
const Matrix4f & GetInverseLocalToWorldMatrix () {return scene_matrix.GetInverseLocalToWorldMatrix();}
const Matrix4f & GetInverseTransposeLocalToWorldMatrix () {return scene_matrix.GetInverseTransposeLocalToWorldMatrix();}
Matrix4f & SetLocalMatrix (const Matrix4f &); ///<设定当前节点矩阵
Matrix4f & SetLocalToWorldMatrix (const Matrix4f &); ///<设定当前节点到世界矩阵
public:
const Matrix4f & GetLocalMatrix ()const {return LocalMatrix;}
const Matrix4f & GetLocalToWorldMatrix ()const {return LocalToWorldMatrix;}
virtual void RefreshMatrix();
};//class SceneOrient
}//namespace hgl::graph
const Matrix4f & GetInverseLocalMatrix ()const {return InverseLocalMatrix;}
const Matrix4f & GetInverseLocalToWorldMatrix()const {return InverseLocalToWorldMatrix;}
public:
virtual void RefreshLocalToWorldMatrix (const Matrix4f *); ///<刷新到世界空间矩阵
};//class SceneOrient
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_SCENE_ORIENT_INCLUDE

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