Compare commits
4 Commits
2aed98d688
...
5ffbe94816
Author | SHA1 | Date | |
---|---|---|---|
5ffbe94816 | |||
2d0e856124 | |||
f8d5b98574 | |||
c3796e7b55 |
@ -57,3 +57,4 @@ testEnv.Program('test/bin/vector-test.out', [catch_cpp, 'test/vector/vector-test
|
|||||||
|
|
||||||
testEnv.Program('test/bin/test-app.out', Glob('test/test-app/*.cpp'))
|
testEnv.Program('test/bin/test-app.out', Glob('test/test-app/*.cpp'))
|
||||||
testEnv.Program('test/bin/parallax-demo.out', Glob('test/parallax-demo/*.cpp'))
|
testEnv.Program('test/bin/parallax-demo.out', Glob('test/parallax-demo/*.cpp'))
|
||||||
|
testEnv.Program('test/bin/particle-demo.out', Glob('test/particle-demo/*.cpp'))
|
||||||
|
95
Shader/bump.fs
Normal file
95
Shader/bump.fs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#version 430 core
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
in VS_OUT {
|
||||||
|
vec3 FragPos;
|
||||||
|
vec2 TexCoords;
|
||||||
|
vec3 TangentLightPos;
|
||||||
|
vec3 TangentViewPos;
|
||||||
|
vec3 TangentFragPos;
|
||||||
|
} fs_in;
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D albedoMap;
|
||||||
|
layout (binding = 1) uniform sampler2D normalMap;
|
||||||
|
layout (binding = 2) uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
uniform float bump_depth;
|
||||||
|
uniform float number_of_steps;
|
||||||
|
uniform float number_of_refinement_steps;
|
||||||
|
|
||||||
|
vec2 get_parallax_offset_uv(vec2 uv, vec3 view_direction) {
|
||||||
|
float layer_depth = 1.0 / number_of_steps;
|
||||||
|
float refinement_layer_depth = layer_depth / number_of_refinement_steps;
|
||||||
|
|
||||||
|
float current_layer_depth = 0.0;
|
||||||
|
|
||||||
|
// the amount to shift the texture coordinates per layer (from vector total_uv_shift)
|
||||||
|
vec2 total_uv_shift = view_direction.xy / view_direction.z * bump_depth;
|
||||||
|
vec2 uv_shift_per_layer = total_uv_shift / number_of_steps;
|
||||||
|
vec2 uv_refine_shift_per_layer = total_uv_shift / (number_of_steps * number_of_refinement_steps);
|
||||||
|
|
||||||
|
// Initial values
|
||||||
|
vec2 current_uv = uv;
|
||||||
|
float current_bump_value = 1.0 - texture(depthMap, current_uv).r;
|
||||||
|
|
||||||
|
// Loop until our depth is greater than the value in the bump map, meaning our ray collided
|
||||||
|
while(current_layer_depth < current_bump_value) {
|
||||||
|
current_uv -= uv_shift_per_layer;
|
||||||
|
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
|
||||||
|
current_layer_depth += layer_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse the last operations so we're at the point before the collision
|
||||||
|
current_uv += uv_shift_per_layer;
|
||||||
|
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
|
||||||
|
|
||||||
|
// Loop again for the refinement steps
|
||||||
|
while(current_layer_depth < current_bump_value) {
|
||||||
|
current_uv -= uv_refine_shift_per_layer;
|
||||||
|
current_bump_value = 1.0 - texture(depthMap, current_uv).r;
|
||||||
|
current_layer_depth += refinement_layer_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Referse the UV operation again and return the result
|
||||||
|
current_uv += uv_refine_shift_per_layer;
|
||||||
|
|
||||||
|
return current_uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Offset texture coordinates with Parallax Mapping
|
||||||
|
vec3 view_direction = normalize(fs_in.TangentViewPos - fs_in.TangentFragPos);
|
||||||
|
vec2 uv = fs_in.TexCoords;
|
||||||
|
|
||||||
|
uv = get_parallax_offset_uv(fs_in.TexCoords, view_direction);
|
||||||
|
|
||||||
|
// Discard if the parallax offset moved us outside of the texture
|
||||||
|
if (uv.x > 1.0 || uv.y > 1.0 || uv.x < 0.0 || uv.y < 0.0)
|
||||||
|
discard;
|
||||||
|
|
||||||
|
// Get normal from normal map and scale it to -1..1
|
||||||
|
vec3 normal = texture(normalMap, uv).rgb;
|
||||||
|
normal = normalize(normal * 2.0 - 1.0);
|
||||||
|
|
||||||
|
// Get albedo color
|
||||||
|
vec3 color = texture(albedoMap, uv).rgb;
|
||||||
|
|
||||||
|
// Ambient lighting
|
||||||
|
vec3 ambient = 0.1 * color;
|
||||||
|
|
||||||
|
// Apply albedo with intensity based on the dot product between the light direction and the normal here
|
||||||
|
vec3 light_direction = normalize(fs_in.TangentLightPos - fs_in.TangentFragPos);
|
||||||
|
float light_normal_dot = max(dot(light_direction, normal), 0.0);
|
||||||
|
vec3 albedo = light_normal_dot * color;
|
||||||
|
|
||||||
|
// Specular lighting
|
||||||
|
vec3 halfway_reflected_light_direction = normalize(light_direction + view_direction);
|
||||||
|
float spec = pow(max(dot(normal, halfway_reflected_light_direction), 0.0), 32.0);
|
||||||
|
|
||||||
|
vec3 specular = vec3(0.2) * spec;
|
||||||
|
|
||||||
|
// Apply
|
||||||
|
FragColor = vec4(ambient + albedo + specular, 1.0);
|
||||||
|
}
|
||||||
|
|
37
Shader/bump.vs
Normal file
37
Shader/bump.vs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
layout (location = 1) in vec3 aNormal;
|
||||||
|
layout (location = 2) in vec2 aTexCoords;
|
||||||
|
layout (location = 3) in vec3 aTangent;
|
||||||
|
layout (location = 4) in vec3 aBitangent;
|
||||||
|
|
||||||
|
out VS_OUT {
|
||||||
|
vec3 FragPos;
|
||||||
|
vec2 TexCoords;
|
||||||
|
vec3 TangentLightPos;
|
||||||
|
vec3 TangentViewPos;
|
||||||
|
vec3 TangentFragPos;
|
||||||
|
} vs_out;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
uniform mat4 model;
|
||||||
|
|
||||||
|
uniform vec3 lightPos;
|
||||||
|
uniform vec3 viewPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||||
|
vs_out.FragPos = vec3(model * vec4(aPos, 1.0));
|
||||||
|
vs_out.TexCoords = aTexCoords;
|
||||||
|
|
||||||
|
vec3 T = normalize(mat3(model) * aTangent);
|
||||||
|
vec3 B = normalize(mat3(model) * aBitangent);
|
||||||
|
vec3 N = normalize(mat3(model) * aNormal);
|
||||||
|
mat3 TBN = transpose(mat3(T, B, N));
|
||||||
|
|
||||||
|
vs_out.TangentLightPos = TBN * lightPos;
|
||||||
|
vs_out.TangentViewPos = TBN * viewPos;
|
||||||
|
vs_out.TangentFragPos = TBN * vs_out.FragPos;
|
||||||
|
}
|
15
Shader/mc.fs
Normal file
15
Shader/mc.fs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler3D densities;
|
||||||
|
layout (binding = 1) uniform sampler2D albedo;
|
||||||
|
layout (binding = 2) uniform sampler2D bump;
|
||||||
|
|
||||||
|
in vec3 varTextureG;
|
||||||
|
in vec2 varUV;
|
||||||
|
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec3 f = texture(albedo, varUV).rgb;
|
||||||
|
color = vec4(f, 1.0);
|
||||||
|
}
|
204
Shader/mc.gs
Normal file
204
Shader/mc.gs
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (points) in;
|
||||||
|
layout (triangle_strip, max_vertices = 12) out;
|
||||||
|
|
||||||
|
uniform mat4 proj;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
in vec3 varTexture[];
|
||||||
|
in int varIndex[];
|
||||||
|
|
||||||
|
out vec3 varTextureG;
|
||||||
|
out vec2 varUV;
|
||||||
|
|
||||||
|
vec3 vectors[13] = {
|
||||||
|
vec3(0.0, 0.0, 0.0), vec3(0.5, 1.0, 1.0), vec3(0.0, 0.5, 1.0),
|
||||||
|
vec3(0.0, 1.0, 0.5), vec3(1.0, 0.5, 1.0), vec3(1.0, 1.0, 0.5),
|
||||||
|
vec3(0.5, 1.0, 0.0), vec3(1.0, 0.5, 0.0), vec3(0.0, 0.5, 0.0),
|
||||||
|
vec3(0.0, 0.0, 0.5), vec3(0.5, 0.0, 1.0), vec3(1.0, 0.0, 0.5),
|
||||||
|
vec3(0.5, 0.0, 0.0)};
|
||||||
|
|
||||||
|
int table[3072] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 4, 1, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5,
|
||||||
|
2, 5, 2, 4, 0, 0, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 5, 6, 7, 3, 1, 2, 0, 0, 0, 0, 0, 0, 7, 4, 6, 4,
|
||||||
|
6, 1, 0, 0, 0, 0, 0, 0, 3, 6, 2, 7, 6, 2, 7, 2, 4, 0, 0,
|
||||||
|
0, 3, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 8, 1, 8, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 6, 3, 8, 1, 5, 4, 0, 0, 0, 0, 0, 0, 6,
|
||||||
|
5, 8, 4, 5, 8, 4, 8, 2, 0, 0, 0, 5, 3, 7, 3, 7, 8, 0, 0,
|
||||||
|
0, 0, 0, 0, 5, 1, 7, 2, 1, 7, 2, 7, 8, 0, 0, 0, 1, 3, 4,
|
||||||
|
8, 3, 4, 8, 4, 7, 0, 0, 0, 8, 7, 2, 4, 7, 2, 0, 0, 0, 0,
|
||||||
|
0, 0, 9, 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 3, 10, 3, 10,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 4, 1, 5, 2, 10, 9, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 10, 5, 9, 10, 5, 9, 5, 3, 0, 0, 0, 9, 2, 10, 5, 7, 6, 0,
|
||||||
|
0, 0, 0, 0, 0, 9, 3, 10, 3, 10, 1, 7, 6, 5, 0, 0, 0, 7, 4,
|
||||||
|
6, 4, 6, 1, 9, 10, 2, 0, 0, 0, 4, 10, 7, 3, 10, 7, 3, 10, 9,
|
||||||
|
3, 6, 7, 9, 2, 10, 3, 8, 6, 0, 0, 0, 0, 0, 0, 9, 8, 10, 6,
|
||||||
|
8, 10, 6, 10, 1, 0, 0, 0, 6, 8, 3, 10, 2, 9, 1, 4, 5, 0, 0,
|
||||||
|
0, 4, 5, 6, 4, 10, 6, 8, 10, 6, 8, 10, 9, 5, 3, 7, 3, 7, 8,
|
||||||
|
10, 2, 9, 0, 0, 0, 9, 7, 1, 9, 10, 1, 5, 7, 1, 9, 7, 8, 9,
|
||||||
|
10, 8, 4, 10, 8, 4, 10, 7, 3, 2, 1, 9, 10, 8, 4, 10, 8, 4, 8,
|
||||||
|
7, 0, 0, 0, 10, 4, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 4, 11,
|
||||||
|
1, 2, 3, 0, 0, 0, 0, 0, 0, 5, 11, 1, 11, 1, 10, 0, 0, 0, 0,
|
||||||
|
0, 0, 10, 2, 11, 3, 2, 11, 3, 11, 5, 0, 0, 0, 7, 5, 6, 4, 11,
|
||||||
|
10, 0, 0, 0, 0, 0, 0, 3, 2, 1, 11, 4, 10, 5, 7, 6, 0, 0, 0,
|
||||||
|
7, 11, 6, 10, 11, 6, 10, 6, 1, 0, 0, 0, 7, 6, 3, 7, 11, 3, 2,
|
||||||
|
11, 3, 2, 11, 10, 10, 4, 11, 6, 8, 3, 0, 0, 0, 0, 0, 0, 6, 1,
|
||||||
|
8, 1, 8, 2, 11, 4, 10, 0, 0, 0, 10, 1, 11, 1, 11, 5, 8, 3, 6,
|
||||||
|
0, 0, 0, 10, 8, 5, 10, 11, 5, 6, 8, 5, 10, 8, 2, 8, 7, 3, 7,
|
||||||
|
3, 5, 10, 11, 4, 0, 0, 0, 10, 11, 2, 7, 11, 2, 7, 11, 8, 1, 4,
|
||||||
|
5, 7, 11, 8, 1, 11, 8, 1, 11, 10, 1, 3, 8, 10, 11, 2, 7, 11, 2,
|
||||||
|
7, 2, 8, 0, 0, 0, 11, 9, 4, 9, 4, 2, 0, 0, 0, 0, 0, 0, 1,
|
||||||
|
4, 3, 11, 4, 3, 11, 3, 9, 0, 0, 0, 2, 1, 9, 5, 1, 9, 5, 9,
|
||||||
|
11, 0, 0, 0, 3, 5, 9, 11, 5, 9, 0, 0, 0, 0, 0, 0, 2, 4, 9,
|
||||||
|
4, 9, 11, 6, 5, 7, 0, 0, 0, 7, 6, 11, 3, 6, 11, 3, 6, 9, 4,
|
||||||
|
5, 1, 7, 1, 9, 7, 11, 9, 2, 1, 9, 7, 1, 6, 7, 6, 11, 3, 6,
|
||||||
|
11, 3, 11, 9, 0, 0, 0, 11, 9, 4, 9, 4, 2, 6, 8, 3, 0, 0, 0,
|
||||||
|
1, 4, 6, 9, 4, 6, 9, 4, 11, 9, 8, 6, 6, 8, 5, 9, 8, 5, 9,
|
||||||
|
8, 11, 1, 3, 2, 6, 8, 5, 9, 8, 5, 9, 5, 11, 0, 0, 0, 7, 11,
|
||||||
|
9, 7, 9, 9, 5, 4, 2, 5, 2, 2, 9, 11, 8, 11, 8, 7, 1, 4, 5,
|
||||||
|
0, 0, 0, 7, 8, 11, 8, 11, 9, 1, 3, 2, 0, 0, 0, 9, 11, 8, 11,
|
||||||
|
8, 7, 0, 0, 0, 0, 0, 0, 11, 7, 12, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 11, 7, 12, 3, 2, 1, 0, 0, 0, 0, 0, 0, 11, 7, 12, 5, 4, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 2, 4, 12, 7, 11, 0, 0, 0, 11,
|
||||||
|
5, 12, 5, 12, 6, 0, 0, 0, 0, 0, 0, 11, 5, 12, 5, 12, 6, 2, 1,
|
||||||
|
3, 0, 0, 0, 11, 4, 12, 1, 4, 12, 1, 12, 6, 0, 0, 0, 11, 2, 6,
|
||||||
|
11, 12, 6, 3, 2, 6, 11, 2, 4, 7, 12, 11, 8, 6, 3, 0, 0, 0, 0,
|
||||||
|
0, 0, 2, 8, 1, 8, 1, 6, 11, 12, 7, 0, 0, 0, 1, 4, 5, 12, 7,
|
||||||
|
11, 6, 8, 3, 0, 0, 0, 11, 12, 4, 8, 12, 4, 8, 12, 2, 5, 7, 6,
|
||||||
|
8, 12, 3, 11, 12, 3, 11, 3, 5, 0, 0, 0, 8, 12, 2, 5, 12, 2, 5,
|
||||||
|
12, 11, 5, 1, 2, 8, 3, 1, 8, 12, 1, 4, 12, 1, 4, 12, 11, 11, 12,
|
||||||
|
4, 8, 12, 4, 8, 4, 2, 0, 0, 0, 12, 11, 7, 10, 9, 2, 0, 0, 0,
|
||||||
|
0, 0, 0, 1, 10, 3, 10, 3, 9, 7, 11, 12, 0, 0, 0, 12, 7, 11, 1,
|
||||||
|
4, 5, 10, 2, 9, 0, 0, 0, 12, 7, 9, 5, 7, 9, 5, 7, 3, 10, 11,
|
||||||
|
4, 6, 12, 5, 12, 5, 11, 2, 9, 10, 0, 0, 0, 12, 9, 3, 12, 3, 3,
|
||||||
|
11, 10, 1, 11, 1, 1, 11, 4, 12, 1, 4, 12, 1, 4, 6, 9, 10, 2, 3,
|
||||||
|
9, 6, 9, 6, 12, 4, 10, 11, 0, 0, 0, 3, 6, 8, 11, 12, 7, 9, 10,
|
||||||
|
2, 0, 0, 0, 7, 11, 6, 10, 11, 6, 10, 11, 1, 8, 12, 9, 12, 8, 9,
|
||||||
|
6, 7, 5, 1, 2, 3, 6, 7, 5, 9, 8, 12, 5, 7, 6, 11, 4, 10, 0,
|
||||||
|
0, 0, 8, 12, 3, 11, 12, 3, 11, 12, 5, 2, 9, 10, 5, 11, 1, 11, 1,
|
||||||
|
10, 8, 12, 9, 0, 0, 0, 8, 12, 9, 4, 10, 11, 2, 1, 3, 0, 0, 0,
|
||||||
|
11, 10, 4, 9, 12, 8, 0, 0, 0, 0, 0, 0, 12, 10, 7, 10, 7, 4, 0,
|
||||||
|
0, 0, 0, 0, 0, 12, 10, 7, 10, 7, 4, 3, 2, 1, 0, 0, 0, 5, 7,
|
||||||
|
1, 12, 7, 1, 12, 1, 10, 0, 0, 0, 12, 7, 10, 3, 7, 10, 3, 7, 5,
|
||||||
|
3, 2, 10, 4, 5, 10, 6, 5, 10, 6, 10, 12, 0, 0, 0, 4, 5, 10, 6,
|
||||||
|
5, 10, 6, 5, 12, 2, 1, 3, 12, 6, 10, 1, 6, 10, 0, 0, 0, 0, 0,
|
||||||
|
0, 3, 2, 6, 10, 2, 6, 10, 6, 12, 0, 0, 0, 4, 7, 10, 7, 10, 12,
|
||||||
|
3, 6, 8, 0, 0, 0, 6, 8, 2, 6, 2, 2, 7, 12, 10, 7, 10, 10, 5,
|
||||||
|
7, 1, 12, 7, 1, 12, 7, 10, 3, 6, 8, 10, 12, 2, 12, 2, 8, 5, 7,
|
||||||
|
6, 0, 0, 0, 4, 12, 3, 4, 5, 3, 8, 12, 3, 4, 12, 10, 8, 2, 12,
|
||||||
|
2, 12, 10, 5, 1, 4, 0, 0, 0, 8, 3, 12, 1, 3, 12, 1, 12, 10, 0,
|
||||||
|
0, 0, 10, 12, 2, 12, 2, 8, 0, 0, 0, 0, 0, 0, 12, 9, 7, 2, 9,
|
||||||
|
7, 2, 7, 4, 0, 0, 0, 12, 4, 3, 12, 9, 3, 1, 4, 3, 12, 4, 7,
|
||||||
|
2, 1, 5, 2, 9, 5, 7, 9, 5, 7, 9, 12, 12, 7, 9, 5, 7, 9, 5,
|
||||||
|
9, 3, 0, 0, 0, 2, 9, 4, 6, 9, 4, 6, 9, 12, 6, 5, 4, 12, 6,
|
||||||
|
9, 6, 9, 3, 4, 5, 1, 0, 0, 0, 2, 9, 1, 12, 9, 1, 12, 1, 6,
|
||||||
|
0, 0, 0, 3, 9, 6, 9, 6, 12, 0, 0, 0, 0, 0, 0, 12, 9, 7, 2,
|
||||||
|
9, 7, 2, 9, 4, 6, 8, 3, 1, 6, 4, 6, 4, 7, 9, 8, 12, 0, 0,
|
||||||
|
0, 5, 7, 6, 9, 8, 12, 3, 2, 1, 0, 0, 0, 12, 8, 9, 6, 7, 5,
|
||||||
|
0, 0, 0, 0, 0, 0, 4, 2, 5, 2, 5, 3, 12, 9, 8, 0, 0, 0, 12,
|
||||||
|
8, 9, 1, 4, 5, 0, 0, 0, 0, 0, 0, 8, 9, 12, 2, 3, 1, 0, 0,
|
||||||
|
0, 0, 0, 0, 12, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 8, 9,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 12, 2, 3, 1, 0, 0, 0, 0,
|
||||||
|
0, 0, 12, 8, 9, 1, 4, 5, 0, 0, 0, 0, 0, 0, 4, 2, 5, 2, 5,
|
||||||
|
3, 12, 9, 8, 0, 0, 0, 12, 8, 9, 6, 7, 5, 0, 0, 0, 0, 0, 0,
|
||||||
|
5, 7, 6, 9, 8, 12, 3, 2, 1, 0, 0, 0, 1, 6, 4, 6, 4, 7, 9,
|
||||||
|
8, 12, 0, 0, 0, 12, 9, 7, 2, 9, 7, 2, 9, 4, 6, 8, 3, 3, 9,
|
||||||
|
6, 9, 6, 12, 0, 0, 0, 0, 0, 0, 2, 9, 1, 12, 9, 1, 12, 1, 6,
|
||||||
|
0, 0, 0, 12, 6, 9, 6, 9, 3, 4, 5, 1, 0, 0, 0, 2, 9, 4, 6,
|
||||||
|
9, 4, 6, 9, 12, 6, 5, 4, 12, 7, 9, 5, 7, 9, 5, 9, 3, 0, 0,
|
||||||
|
0, 2, 1, 5, 2, 9, 5, 7, 9, 5, 7, 9, 12, 12, 4, 3, 12, 9, 3,
|
||||||
|
1, 4, 3, 12, 4, 7, 12, 9, 7, 2, 9, 7, 2, 7, 4, 0, 0, 0, 10,
|
||||||
|
12, 2, 12, 2, 8, 0, 0, 0, 0, 0, 0, 8, 3, 12, 1, 3, 12, 1, 12,
|
||||||
|
10, 0, 0, 0, 8, 2, 12, 2, 12, 10, 5, 1, 4, 0, 0, 0, 4, 12, 3,
|
||||||
|
4, 5, 3, 8, 12, 3, 4, 12, 10, 10, 12, 2, 12, 2, 8, 5, 7, 6, 0,
|
||||||
|
0, 0, 5, 7, 1, 12, 7, 1, 12, 7, 10, 3, 6, 8, 6, 8, 2, 6, 2,
|
||||||
|
2, 7, 12, 10, 7, 10, 10, 4, 7, 10, 7, 10, 12, 3, 6, 8, 0, 0, 0,
|
||||||
|
3, 2, 6, 10, 2, 6, 10, 6, 12, 0, 0, 0, 12, 6, 10, 1, 6, 10, 0,
|
||||||
|
0, 0, 0, 0, 0, 4, 5, 10, 6, 5, 10, 6, 5, 12, 2, 1, 3, 4, 5,
|
||||||
|
10, 6, 5, 10, 6, 10, 12, 0, 0, 0, 12, 7, 10, 3, 7, 10, 3, 7, 5,
|
||||||
|
3, 2, 10, 5, 7, 1, 12, 7, 1, 12, 1, 10, 0, 0, 0, 12, 10, 7, 10,
|
||||||
|
7, 4, 3, 2, 1, 0, 0, 0, 12, 10, 7, 10, 7, 4, 0, 0, 0, 0, 0,
|
||||||
|
0, 11, 10, 4, 9, 12, 8, 0, 0, 0, 0, 0, 0, 8, 12, 9, 4, 10, 11,
|
||||||
|
2, 1, 3, 0, 0, 0, 5, 11, 1, 11, 1, 10, 8, 12, 9, 0, 0, 0, 8,
|
||||||
|
12, 3, 11, 12, 3, 11, 12, 5, 2, 9, 10, 9, 8, 12, 5, 7, 6, 11, 4,
|
||||||
|
10, 0, 0, 0, 12, 8, 9, 6, 7, 5, 1, 2, 3, 6, 7, 5, 7, 11, 6,
|
||||||
|
10, 11, 6, 10, 11, 1, 8, 12, 9, 3, 6, 8, 11, 12, 7, 9, 10, 2, 0,
|
||||||
|
0, 0, 3, 9, 6, 9, 6, 12, 4, 10, 11, 0, 0, 0, 11, 4, 12, 1, 4,
|
||||||
|
12, 1, 4, 6, 9, 10, 2, 12, 9, 3, 12, 3, 3, 11, 10, 1, 11, 1, 1,
|
||||||
|
6, 12, 5, 12, 5, 11, 2, 9, 10, 0, 0, 0, 12, 7, 9, 5, 7, 9, 5,
|
||||||
|
7, 3, 10, 11, 4, 12, 7, 11, 1, 4, 5, 10, 2, 9, 0, 0, 0, 1, 10,
|
||||||
|
3, 10, 3, 9, 7, 11, 12, 0, 0, 0, 12, 11, 7, 10, 9, 2, 0, 0, 0,
|
||||||
|
0, 0, 0, 11, 12, 4, 8, 12, 4, 8, 4, 2, 0, 0, 0, 8, 3, 1, 8,
|
||||||
|
12, 1, 4, 12, 1, 4, 12, 11, 8, 12, 2, 5, 12, 2, 5, 12, 11, 5, 1,
|
||||||
|
2, 8, 12, 3, 11, 12, 3, 11, 3, 5, 0, 0, 0, 11, 12, 4, 8, 12, 4,
|
||||||
|
8, 12, 2, 5, 7, 6, 1, 4, 5, 12, 7, 11, 6, 8, 3, 0, 0, 0, 2,
|
||||||
|
8, 1, 8, 1, 6, 11, 12, 7, 0, 0, 0, 7, 12, 11, 8, 6, 3, 0, 0,
|
||||||
|
0, 0, 0, 0, 11, 2, 6, 11, 12, 6, 3, 2, 6, 11, 2, 4, 11, 4, 12,
|
||||||
|
1, 4, 12, 1, 12, 6, 0, 0, 0, 11, 5, 12, 5, 12, 6, 2, 1, 3, 0,
|
||||||
|
0, 0, 11, 5, 12, 5, 12, 6, 0, 0, 0, 0, 0, 0, 3, 5, 2, 5, 2,
|
||||||
|
4, 12, 7, 11, 0, 0, 0, 11, 7, 12, 5, 4, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
11, 7, 12, 3, 2, 1, 0, 0, 0, 0, 0, 0, 11, 7, 12, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 9, 11, 8, 11, 8, 7, 0, 0, 0, 0, 0, 0, 7, 8,
|
||||||
|
11, 8, 11, 9, 1, 3, 2, 0, 0, 0, 9, 11, 8, 11, 8, 7, 1, 4, 5,
|
||||||
|
0, 0, 0, 7, 11, 9, 7, 9, 9, 5, 4, 2, 5, 2, 2, 6, 8, 5, 9,
|
||||||
|
8, 5, 9, 5, 11, 0, 0, 0, 6, 8, 5, 9, 8, 5, 9, 8, 11, 1, 3,
|
||||||
|
2, 1, 4, 6, 9, 4, 6, 9, 4, 11, 9, 8, 6, 11, 9, 4, 9, 4, 2,
|
||||||
|
6, 8, 3, 0, 0, 0, 7, 6, 11, 3, 6, 11, 3, 11, 9, 0, 0, 0, 7,
|
||||||
|
1, 9, 7, 11, 9, 2, 1, 9, 7, 1, 6, 7, 6, 11, 3, 6, 11, 3, 6,
|
||||||
|
9, 4, 5, 1, 2, 4, 9, 4, 9, 11, 6, 5, 7, 0, 0, 0, 3, 5, 9,
|
||||||
|
11, 5, 9, 0, 0, 0, 0, 0, 0, 2, 1, 9, 5, 1, 9, 5, 9, 11, 0,
|
||||||
|
0, 0, 1, 4, 3, 11, 4, 3, 11, 3, 9, 0, 0, 0, 11, 9, 4, 9, 4,
|
||||||
|
2, 0, 0, 0, 0, 0, 0, 10, 11, 2, 7, 11, 2, 7, 2, 8, 0, 0, 0,
|
||||||
|
7, 11, 8, 1, 11, 8, 1, 11, 10, 1, 3, 8, 10, 11, 2, 7, 11, 2, 7,
|
||||||
|
11, 8, 1, 4, 5, 8, 7, 3, 7, 3, 5, 10, 11, 4, 0, 0, 0, 10, 8,
|
||||||
|
5, 10, 11, 5, 6, 8, 5, 10, 8, 2, 10, 1, 11, 1, 11, 5, 8, 3, 6,
|
||||||
|
0, 0, 0, 6, 1, 8, 1, 8, 2, 11, 4, 10, 0, 0, 0, 10, 4, 11, 6,
|
||||||
|
8, 3, 0, 0, 0, 0, 0, 0, 7, 6, 3, 7, 11, 3, 2, 11, 3, 2, 11,
|
||||||
|
10, 7, 11, 6, 10, 11, 6, 10, 6, 1, 0, 0, 0, 3, 2, 1, 11, 4, 10,
|
||||||
|
5, 7, 6, 0, 0, 0, 7, 5, 6, 4, 11, 10, 0, 0, 0, 0, 0, 0, 10,
|
||||||
|
2, 11, 3, 2, 11, 3, 11, 5, 0, 0, 0, 5, 11, 1, 11, 1, 10, 0, 0,
|
||||||
|
0, 0, 0, 0, 10, 4, 11, 1, 2, 3, 0, 0, 0, 0, 0, 0, 10, 4, 11,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 8, 4, 10, 8, 4, 8, 7, 0,
|
||||||
|
0, 0, 9, 10, 8, 4, 10, 8, 4, 10, 7, 3, 2, 1, 9, 7, 1, 9, 10,
|
||||||
|
1, 5, 7, 1, 9, 7, 8, 5, 3, 7, 3, 7, 8, 10, 2, 9, 0, 0, 0,
|
||||||
|
4, 5, 6, 4, 10, 6, 8, 10, 6, 8, 10, 9, 6, 8, 3, 10, 2, 9, 1,
|
||||||
|
4, 5, 0, 0, 0, 9, 8, 10, 6, 8, 10, 6, 10, 1, 0, 0, 0, 9, 2,
|
||||||
|
10, 3, 8, 6, 0, 0, 0, 0, 0, 0, 4, 10, 7, 3, 10, 7, 3, 10, 9,
|
||||||
|
3, 6, 7, 7, 4, 6, 4, 6, 1, 9, 10, 2, 0, 0, 0, 9, 3, 10, 3,
|
||||||
|
10, 1, 7, 6, 5, 0, 0, 0, 9, 2, 10, 5, 7, 6, 0, 0, 0, 0, 0,
|
||||||
|
0, 4, 10, 5, 9, 10, 5, 9, 5, 3, 0, 0, 0, 4, 1, 5, 2, 10, 9,
|
||||||
|
0, 0, 0, 0, 0, 0, 9, 3, 10, 3, 10, 1, 0, 0, 0, 0, 0, 0, 9,
|
||||||
|
2, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 7, 2, 4, 7, 2, 0, 0,
|
||||||
|
0, 0, 0, 0, 1, 3, 4, 8, 3, 4, 8, 4, 7, 0, 0, 0, 5, 1, 7,
|
||||||
|
2, 1, 7, 2, 7, 8, 0, 0, 0, 5, 3, 7, 3, 7, 8, 0, 0, 0, 0,
|
||||||
|
0, 0, 6, 5, 8, 4, 5, 8, 4, 8, 2, 0, 0, 0, 6, 3, 8, 1, 5,
|
||||||
|
4, 0, 0, 0, 0, 0, 0, 6, 1, 8, 1, 8, 2, 0, 0, 0, 0, 0, 0,
|
||||||
|
3, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 2, 7, 6, 2, 7,
|
||||||
|
2, 4, 0, 0, 0, 7, 4, 6, 4, 6, 1, 0, 0, 0, 0, 0, 0, 5, 6,
|
||||||
|
7, 3, 1, 2, 0, 0, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 3, 5, 2, 5, 2, 4, 0, 0, 0, 0, 0, 0, 4, 1, 5, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
vec4 base = gl_in[0].gl_Position;
|
||||||
|
int index = varIndex[0] * 12;
|
||||||
|
for(int i = 0; i < 12; i += 3) {
|
||||||
|
// TODO: Calculate tangents
|
||||||
|
vec3 tangent;
|
||||||
|
vec3 bitangent;
|
||||||
|
|
||||||
|
for(int k = 0; k < 3; k++) {
|
||||||
|
gl_Position = proj * view * (base + vec4(vectors[table[index + i + k]], 0.0));
|
||||||
|
varTextureG = varTexture[0];
|
||||||
|
// FIXME: These UV coordinates become stretched on one axis
|
||||||
|
varUV = vectors[table[index + i + k]].xz;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
}
|
38
Shader/mc.vs
Normal file
38
Shader/mc.vs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler3D densities;
|
||||||
|
|
||||||
|
uniform float step;
|
||||||
|
uniform float threshold;
|
||||||
|
|
||||||
|
uniform int size_x;
|
||||||
|
uniform int size_y;
|
||||||
|
uniform int size_z;
|
||||||
|
|
||||||
|
out vec3 varTexture;
|
||||||
|
out int varIndex;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
int id = gl_VertexID;
|
||||||
|
|
||||||
|
// Could be optimized by using bit-wise '>>' and '&', but this is more generic
|
||||||
|
int x = id % size_x;
|
||||||
|
int y = (id / size_x) % size_y;
|
||||||
|
int z = (id / size_x / size_y) % size_z;
|
||||||
|
|
||||||
|
vec3 xyz = vec3(x, y, z);
|
||||||
|
gl_Position = vec4(xyz, 1.0);
|
||||||
|
varTexture = xyz * step;
|
||||||
|
|
||||||
|
int b1 = int(texture(densities, varTexture).r < threshold);
|
||||||
|
int b2 = int(texture(densities, varTexture + vec3(step, 0.0, 0.0)).r < threshold);
|
||||||
|
int b3 = int(texture(densities, varTexture + vec3(step, 0.0, step)).r < threshold);
|
||||||
|
int b4 = int(texture(densities, varTexture + vec3(0.0, 0.0, step)).r < threshold);
|
||||||
|
int b5 = int(texture(densities, varTexture + vec3(0.0, step, 0.0)).r < threshold);
|
||||||
|
int b6 = int(texture(densities, varTexture + vec3(step, step, 0.0)).r < threshold);
|
||||||
|
int b7 = int(texture(densities, varTexture + vec3(step, step, step)).r < threshold);
|
||||||
|
int b8 = int(texture(densities, varTexture + vec3(0.0, step, step)).r < threshold);
|
||||||
|
|
||||||
|
varIndex = (b1 << 7) | (b2 << 6) | (b3 << 5) | (b4 << 4) |
|
||||||
|
(b5 << 3) | (b6 << 2) | (b7 << 1) | b8;
|
||||||
|
}
|
20
Shader/noise.fs
Normal file
20
Shader/noise.fs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
in vec3 varPosition;
|
||||||
|
|
||||||
|
out float noise;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// Base: Distance to a helix
|
||||||
|
vec3 helix_pos = vec3(sin(varPosition.y * 5.0) * 0.2 + 0.5, varPosition.y, cos(varPosition.y * 5.0) * 0.2 + 0.5);
|
||||||
|
float dist = distance(helix_pos, varPosition);
|
||||||
|
|
||||||
|
noise = 0.6 - dist;
|
||||||
|
|
||||||
|
// Create some blobby shapes on the helix
|
||||||
|
float f1 = sin((varPosition.x + varPosition.z) * 7.0);
|
||||||
|
float f2 = cos((varPosition.y + varPosition.x) * 3.0);
|
||||||
|
float f3 = cos((varPosition.z + varPosition.y) * 8.0);
|
||||||
|
|
||||||
|
noise += abs(f1 + f2 + f3) * 0.1;
|
||||||
|
}
|
13
Shader/noise.vs
Normal file
13
Shader/noise.vs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location = 0) in vec2 position;
|
||||||
|
|
||||||
|
uniform float layer;
|
||||||
|
uniform float height;
|
||||||
|
|
||||||
|
out vec3 varPosition;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
gl_Position = vec4(position, 0.0, 1.0);
|
||||||
|
varPosition = vec3(position.x, position.y + height, layer);
|
||||||
|
}
|
13
Shader/particle_render.fs
Normal file
13
Shader/particle_render.fs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (binding = 0) uniform sampler2D texture;
|
||||||
|
|
||||||
|
smooth in vec2 tex_coords;
|
||||||
|
flat in vec4 color_part;
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = texture2D(texture, tex_coords) * color_part;
|
||||||
|
}
|
54
Shader/particle_render.gs
Normal file
54
Shader/particle_render.gs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
uniform mat4 view;
|
||||||
|
|
||||||
|
uniform vec3 quad1, quad2;
|
||||||
|
|
||||||
|
layout(points) in;
|
||||||
|
layout(triangle_strip) out;
|
||||||
|
layout(max_vertices = 4) out;
|
||||||
|
|
||||||
|
in vec3 color_pass[];
|
||||||
|
in float lifetime_pass[];
|
||||||
|
in float size_pass[];
|
||||||
|
in int type_pass[];
|
||||||
|
|
||||||
|
smooth out vec2 tex_coords;
|
||||||
|
flat out vec4 color_part;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if(type_pass[0] != 0) {
|
||||||
|
// This is not a generator particle
|
||||||
|
|
||||||
|
vec3 old_pos = gl_in[0].gl_Position.xyz;
|
||||||
|
float size = size_pass[0];
|
||||||
|
mat4 view_projection_matrix = projection * view;
|
||||||
|
|
||||||
|
color_part = vec4(color_pass[0], lifetime_pass[0]);
|
||||||
|
|
||||||
|
vec3 pos = old_pos + (-quad1 - quad2) * size;
|
||||||
|
tex_coords = vec2(0.0, 0.0);
|
||||||
|
|
||||||
|
gl_Position = view_projection_matrix * vec4(pos, 1.0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
pos = old_pos + (-quad1 + quad2) * size;
|
||||||
|
tex_coords = vec2(0.0, 1.0);
|
||||||
|
gl_Position = view_projection_matrix * vec4(pos, 1.0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
pos = old_pos + (quad1 - quad2) * size;
|
||||||
|
tex_coords = vec2(1.0, 0.0);
|
||||||
|
gl_Position = view_projection_matrix * vec4(pos, 1.0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
pos = old_pos + (quad1 + quad2) * size;
|
||||||
|
tex_coords = vec2(1.0, 1.0);
|
||||||
|
gl_Position = view_projection_matrix * vec4(pos, 1.0);
|
||||||
|
EmitVertex();
|
||||||
|
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
}
|
21
Shader/particle_render.vs
Normal file
21
Shader/particle_render.vs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
layout (location = 2) in vec3 color;
|
||||||
|
layout (location = 3) in float lifetime;
|
||||||
|
layout (location = 4) in float size;
|
||||||
|
layout (location = 5) in int type;
|
||||||
|
|
||||||
|
out vec3 color_pass;
|
||||||
|
out float lifetime_pass;
|
||||||
|
out float size_pass;
|
||||||
|
out int type_pass;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(position, 1.0);
|
||||||
|
color_pass = color;
|
||||||
|
lifetime_pass = lifetime;
|
||||||
|
size_pass = size;
|
||||||
|
type_pass = type;
|
||||||
|
}
|
93
Shader/particle_update.gs
Normal file
93
Shader/particle_update.gs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout(points) in;
|
||||||
|
layout(points) out;
|
||||||
|
layout(max_vertices = 40) out;
|
||||||
|
|
||||||
|
// All that we get from vertex shader
|
||||||
|
in vec3 position_pass[];
|
||||||
|
in vec3 velocity_pass[];
|
||||||
|
in vec3 color_pass[];
|
||||||
|
in float lifetime_pass[];
|
||||||
|
in float size_pass[];
|
||||||
|
in int type_pass[];
|
||||||
|
|
||||||
|
// All that we send further
|
||||||
|
out vec3 position_out;
|
||||||
|
out vec3 velocity_out;
|
||||||
|
out vec3 color_out;
|
||||||
|
out float lifetime_out;
|
||||||
|
out float size_out;
|
||||||
|
out int type_out;
|
||||||
|
|
||||||
|
uniform vec3 spawn_position; // Position where new particles are spawned
|
||||||
|
uniform vec3 spawn_gravity; // Gravity vector for particles - updates velocity of particles
|
||||||
|
uniform vec3 spawn_velocity_min; // Velocity of new particle - from min to (min+range)
|
||||||
|
uniform vec3 spawn_velocity_range;
|
||||||
|
|
||||||
|
uniform vec3 spawn_color;
|
||||||
|
uniform float spawn_size;
|
||||||
|
|
||||||
|
uniform float spawn_lifetime_min, spawn_lifetime_range; // Life of new particle - from min to (min+range)
|
||||||
|
uniform float time_passed; // Time passed since last frame
|
||||||
|
|
||||||
|
uniform vec3 random_seed; // Seed number for our random number function
|
||||||
|
vec3 local_seed;
|
||||||
|
|
||||||
|
uniform int number_to_generate; // How many particles will be generated next time, if greater than zero, particles are generated
|
||||||
|
|
||||||
|
float random_zero_to_one() {
|
||||||
|
uint n = floatBitsToUint(local_seed.y * 214013.0 + local_seed.x * 2531011.0 + local_seed.z * 141251.0);
|
||||||
|
n = n * (n * n * 15731u + 789221u);
|
||||||
|
n = (n >> 9u) | 0x3F800000u;
|
||||||
|
|
||||||
|
float fRes = 2.0 - uintBitsToFloat(n);
|
||||||
|
local_seed = vec3(local_seed.x + 147158.0 * fRes, local_seed.y*fRes + 415161.0 * fRes, local_seed.z + 324154.0*fRes);
|
||||||
|
|
||||||
|
return fRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
local_seed = random_seed;
|
||||||
|
|
||||||
|
// gl_Position doesn't matter now, as rendering is discarded
|
||||||
|
|
||||||
|
position_out = position_pass[0];
|
||||||
|
velocity_out = velocity_pass[0];
|
||||||
|
|
||||||
|
if(type_pass[0] != 0) position_out += velocity_out * time_passed;
|
||||||
|
if(type_pass[0] != 0) velocity_out += spawn_gravity * time_passed;
|
||||||
|
|
||||||
|
color_out = color_pass[0];
|
||||||
|
lifetime_out = lifetime_pass[0] - time_passed;
|
||||||
|
size_out = size_pass[0];
|
||||||
|
type_out = type_pass[0];
|
||||||
|
|
||||||
|
if(type_out == 0) {
|
||||||
|
// This is the emitter particle
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
|
||||||
|
for(int i = 0; i < number_to_generate; i++)
|
||||||
|
{
|
||||||
|
position_out = spawn_position;
|
||||||
|
velocity_out = spawn_velocity_min + vec3(
|
||||||
|
spawn_velocity_range.x * random_zero_to_one(),
|
||||||
|
spawn_velocity_range.y * random_zero_to_one(),
|
||||||
|
spawn_velocity_range.z * random_zero_to_one()
|
||||||
|
);
|
||||||
|
|
||||||
|
color_out = spawn_color;
|
||||||
|
lifetime_out = spawn_lifetime_min + spawn_lifetime_range * random_zero_to_one();
|
||||||
|
size_out = spawn_size;
|
||||||
|
type_out = 1;
|
||||||
|
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
} else if(lifetime_out > 0.0) {
|
||||||
|
// This is a normal particle which is still alive
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
}
|
24
Shader/particle_update.vs
Normal file
24
Shader/particle_update.vs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 position;
|
||||||
|
layout (location = 1) in vec3 velocity;
|
||||||
|
layout (location = 2) in vec3 color;
|
||||||
|
layout (location = 3) in float lifetime;
|
||||||
|
layout (location = 4) in float size;
|
||||||
|
layout (location = 5) in int type;
|
||||||
|
|
||||||
|
out vec3 position_pass;
|
||||||
|
out vec3 velocity_pass;
|
||||||
|
out vec3 color_pass;
|
||||||
|
out float lifetime_pass;
|
||||||
|
out float size_pass;
|
||||||
|
out int type_pass;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
position_pass = position;
|
||||||
|
velocity_pass = velocity;
|
||||||
|
color_pass = color;
|
||||||
|
lifetime_pass = lifetime;
|
||||||
|
size_pass = size;
|
||||||
|
type_pass = type;
|
||||||
|
}
|
13
Shader/text.fs
Normal file
13
Shader/text.fs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
in vec2 TexCoords;
|
||||||
|
out vec4 color;
|
||||||
|
|
||||||
|
uniform sampler2D text;
|
||||||
|
uniform vec3 textColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
|
||||||
|
color = vec4(textColor, 1.0) * sampled;
|
||||||
|
}
|
12
Shader/text.vs
Normal file
12
Shader/text.vs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#version 430
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 vertex; // <vec2 pos, vec2 tex>
|
||||||
|
out vec2 TexCoords;
|
||||||
|
|
||||||
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = projection * vec4(vertex.xy, 0.0, 1.0);
|
||||||
|
TexCoords = vertex.zw;
|
||||||
|
}
|
165
cpp/ParticleSystem.cpp
Normal file
165
cpp/ParticleSystem.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#include "Gedeng/ParticleSystem.h"
|
||||||
|
#include "Gedeng/Logger.h"
|
||||||
|
|
||||||
|
namespace Gedeng {
|
||||||
|
|
||||||
|
ParticleSystem::ParticleSystem() {
|
||||||
|
const char *varyings[6] = {"position_out", "velocity_out", "color_out", "lifetime_out", "size_out", "type_out"};
|
||||||
|
|
||||||
|
update_shader.add_vertex_shader("Shader/particle_update.vs");
|
||||||
|
update_shader.add_geometry_shader("Shader/particle_update.gs");
|
||||||
|
update_shader.add_transform_feedback(varyings, 6);
|
||||||
|
update_shader.link();
|
||||||
|
|
||||||
|
glGenTransformFeedbacks(1, &transform_feedback_buffer);
|
||||||
|
|
||||||
|
render_shader.add_fragment_shader("Shader/particle_render.fs");
|
||||||
|
render_shader.add_vertex_shader("Shader/particle_render.vs");
|
||||||
|
render_shader.add_geometry_shader("Shader/particle_render.gs");
|
||||||
|
render_shader.link();
|
||||||
|
|
||||||
|
glGenQueries(1, &query);
|
||||||
|
|
||||||
|
glGenBuffers(2, particle_buffer);
|
||||||
|
glGenVertexArrays(2, vao);
|
||||||
|
|
||||||
|
Particle part_initialization;
|
||||||
|
part_initialization.type = PARTICLE_TYPE_GENERATOR;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
glBindVertexArray(vao[i]);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, particle_buffer[i]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(Particle) * max_particle_count, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Particle), &part_initialization);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
glEnableVertexAttribArray(i);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)0); // Position
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)12); // Velocity
|
||||||
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)24); // Color
|
||||||
|
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)36); // Lifetime
|
||||||
|
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(Particle), (const GLvoid *)40); // Size
|
||||||
|
glVertexAttribPointer(5, 1, GL_INT, GL_FALSE, sizeof(Particle), (const GLvoid *)44); // Type
|
||||||
|
}
|
||||||
|
|
||||||
|
current_read_buffer = 0;
|
||||||
|
current_particle_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::update(float delta) {
|
||||||
|
update_shader.use();
|
||||||
|
|
||||||
|
update_shader.setFloat("time_passed", elapsed_time);
|
||||||
|
update_shader.setVec3("spawn_position", spawn_position);
|
||||||
|
update_shader.setVec3("spawn_velocity_min", spawn_velocity_min);
|
||||||
|
update_shader.setVec3("spawn_velocity_range", spawn_velocity_range);
|
||||||
|
update_shader.setVec3("spawn_color", spawn_color);
|
||||||
|
update_shader.setVec3("spawn_gravity", spawn_gravity_vector);
|
||||||
|
|
||||||
|
update_shader.setFloat("spawn_lifetime_min", spawn_lifetime_min);
|
||||||
|
update_shader.setFloat("spawn_lifetime_range", spawn_lifetime_range);
|
||||||
|
|
||||||
|
update_shader.setFloat("spawn_size", spawn_size);
|
||||||
|
update_shader.setInt("number_to_generate", 0);
|
||||||
|
|
||||||
|
elapsed_time += delta;
|
||||||
|
|
||||||
|
if (elapsed_time > next_generation_time) {
|
||||||
|
update_shader.setInt("number_to_generate", target_particle_count);
|
||||||
|
elapsed_time -= next_generation_time;
|
||||||
|
|
||||||
|
glm::vec3 random_seed = glm::vec3(
|
||||||
|
10.0, 10.0,
|
||||||
|
10.0); // FIXME: Random glm::vec3(grandf(-10.0f, 20.0f), grandf(-10.0f, 20.0f), grandf(-10.0f, 20.0f));
|
||||||
|
update_shader.setVec3("random_seed", random_seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_RASTERIZER_DISCARD);
|
||||||
|
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transform_feedback_buffer);
|
||||||
|
|
||||||
|
glBindVertexArray(vao[current_read_buffer]);
|
||||||
|
glEnableVertexAttribArray(1); // Re-enable velocity
|
||||||
|
|
||||||
|
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, particle_buffer[1 - current_read_buffer]);
|
||||||
|
|
||||||
|
glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
|
||||||
|
glBeginTransformFeedback(GL_POINTS);
|
||||||
|
|
||||||
|
glDrawArrays(GL_POINTS, 0, current_particle_count);
|
||||||
|
|
||||||
|
glEndTransformFeedback();
|
||||||
|
|
||||||
|
glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
|
||||||
|
glGetQueryObjectiv(query, GL_QUERY_RESULT, ¤t_particle_count);
|
||||||
|
|
||||||
|
current_read_buffer = 1 - current_read_buffer;
|
||||||
|
|
||||||
|
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::set_camera(const Camera &camera) {
|
||||||
|
projection_matrix = camera.get_projection();
|
||||||
|
view_matrix = camera.get_view();
|
||||||
|
|
||||||
|
quad1 = glm::cross(camera.forward(), camera.up());
|
||||||
|
quad1 = glm::normalize(quad1);
|
||||||
|
|
||||||
|
quad2 = glm::cross(camera.forward(), quad1);
|
||||||
|
quad2 = glm::normalize(quad2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::render() {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
glDepthMask(0);
|
||||||
|
|
||||||
|
glDisable(GL_RASTERIZER_DISCARD);
|
||||||
|
render_shader.use();
|
||||||
|
render_shader.setMat4("projection", projection_matrix);
|
||||||
|
render_shader.setMat4("view", view_matrix);
|
||||||
|
render_shader.setVec3("quad1", quad1);
|
||||||
|
render_shader.setVec3("quad2", quad2);
|
||||||
|
|
||||||
|
texture->bind_to(0);
|
||||||
|
|
||||||
|
glBindVertexArray(vao[current_read_buffer]);
|
||||||
|
glDisableVertexAttribArray(1); // Disable velocity, because we don't need it for rendering
|
||||||
|
|
||||||
|
glDrawArrays(GL_POINTS, 0, current_particle_count);
|
||||||
|
|
||||||
|
glDepthMask(1);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::set_position(glm::vec3 position) {
|
||||||
|
this->spawn_position = position;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_velocity(glm::vec3 min, glm::vec3 max) {
|
||||||
|
this->spawn_velocity_min = min;
|
||||||
|
this->spawn_velocity_range = max - min;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_gravity(glm::vec3 gravity) {
|
||||||
|
this->spawn_gravity_vector = gravity;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_color(glm::vec3 color) {
|
||||||
|
this->spawn_color = color;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_lifetime(float min, float max) {
|
||||||
|
this->spawn_lifetime_min = min;
|
||||||
|
this->spawn_lifetime_range = max - min;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_size(float size) {
|
||||||
|
this->spawn_size = size;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_interval(float interval) {
|
||||||
|
this->next_generation_time = interval;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_number_of_particles(int number) {
|
||||||
|
this->target_particle_count = number;
|
||||||
|
}
|
||||||
|
void ParticleSystem::set_texture(Texture *texture) {
|
||||||
|
this->texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Gedeng
|
@ -4,8 +4,8 @@ namespace Gedeng {
|
|||||||
|
|
||||||
void RenderBackend::initialize_window(unsigned int width, unsigned int height, String title) {
|
void RenderBackend::initialize_window(unsigned int width, unsigned int height, String title) {
|
||||||
glfwInit();
|
glfwInit();
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
@ -17,9 +17,9 @@ void RenderBackend::initialize_window(unsigned int width, unsigned int height, S
|
|||||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_CULL_FACE);
|
// glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_BLEND);
|
// glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderBackend::is_window_created() {
|
bool RenderBackend::is_window_created() {
|
||||||
|
4857
cpp/vendor/glad.c
vendored
4857
cpp/vendor/glad.c
vendored
File diff suppressed because it is too large
Load Diff
@ -16,11 +16,11 @@ class Camera : public Spatial {
|
|||||||
: projection(glm::perspective(glm::radians(fov), width / height, near, far)) {
|
: projection(glm::perspective(glm::radians(fov), width / height, near, far)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 get_projection() {
|
glm::mat4 get_projection() const {
|
||||||
return projection;
|
return projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 get_view() {
|
glm::mat4 get_view() const {
|
||||||
return glm::inverse(get_matrix());
|
return glm::inverse(get_matrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,4 +28,4 @@ class Camera : public Spatial {
|
|||||||
glm::mat4 projection;
|
glm::mat4 projection;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace Gedeng
|
88
include/Gedeng/ParticleSystem.h
Normal file
88
include/Gedeng/ParticleSystem.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Must be the first include
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
// Other includes
|
||||||
|
#include "Gedeng/Camera.h"
|
||||||
|
#include "Gedeng/Shader.h"
|
||||||
|
#include "Gedeng/Texture.h"
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
namespace Gedeng {
|
||||||
|
|
||||||
|
class ParticleSystem {
|
||||||
|
public:
|
||||||
|
enum { PARTICLE_TYPE_GENERATOR = 0, PARTICLE_TYPE_NORMAL = 1 };
|
||||||
|
|
||||||
|
ParticleSystem();
|
||||||
|
|
||||||
|
void render();
|
||||||
|
|
||||||
|
void update(float delta);
|
||||||
|
|
||||||
|
void set_position(glm::vec3 position);
|
||||||
|
void set_velocity(glm::vec3 min, glm::vec3 max);
|
||||||
|
void set_gravity(glm::vec3 gravity);
|
||||||
|
void set_color(glm::vec3 color);
|
||||||
|
void set_lifetime(float min, float max);
|
||||||
|
void set_size(float size);
|
||||||
|
void set_interval(float interval);
|
||||||
|
void set_number_of_particles(int number);
|
||||||
|
void set_texture(Texture *texture);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void release();
|
||||||
|
|
||||||
|
int get_particle_count();
|
||||||
|
|
||||||
|
void set_camera(const Camera &camera);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool is_valid;
|
||||||
|
|
||||||
|
GLuint transform_feedback_buffer;
|
||||||
|
|
||||||
|
GLuint particle_buffer[2];
|
||||||
|
GLuint vao[2];
|
||||||
|
|
||||||
|
GLuint query;
|
||||||
|
|
||||||
|
Texture *texture;
|
||||||
|
|
||||||
|
int current_read_buffer;
|
||||||
|
int current_particle_count;
|
||||||
|
const int max_particle_count = 1000; // FIXME: Increase
|
||||||
|
|
||||||
|
glm::mat4 projection_matrix, view_matrix;
|
||||||
|
glm::vec3 quad1, quad2;
|
||||||
|
|
||||||
|
float elapsed_time;
|
||||||
|
float next_generation_time;
|
||||||
|
|
||||||
|
glm::vec3 spawn_position;
|
||||||
|
glm::vec3 spawn_velocity_min, spawn_velocity_range;
|
||||||
|
glm::vec3 spawn_gravity_vector;
|
||||||
|
glm::vec3 spawn_color;
|
||||||
|
|
||||||
|
float spawn_lifetime_min, spawn_lifetime_range;
|
||||||
|
float spawn_size;
|
||||||
|
|
||||||
|
int target_particle_count;
|
||||||
|
|
||||||
|
Shader render_shader;
|
||||||
|
Shader update_shader;
|
||||||
|
|
||||||
|
class Particle {
|
||||||
|
public:
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 velocity;
|
||||||
|
glm::vec3 color;
|
||||||
|
float lifetime;
|
||||||
|
float size;
|
||||||
|
int type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Gedeng
|
@ -3,6 +3,7 @@
|
|||||||
// Adapted from LearnOpenGL
|
// Adapted from LearnOpenGL
|
||||||
|
|
||||||
// Must be the first include
|
// Must be the first include
|
||||||
|
#include "Gedeng/Logger.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
// Other includes
|
// Other includes
|
||||||
@ -17,82 +18,70 @@
|
|||||||
namespace Gedeng {
|
namespace Gedeng {
|
||||||
|
|
||||||
class Shader {
|
class Shader {
|
||||||
|
private:
|
||||||
|
unsigned int load_shader(const char *path, GLuint type) {
|
||||||
|
std::string code;
|
||||||
|
std::ifstream file;
|
||||||
|
|
||||||
|
file.open(path);
|
||||||
|
std::stringstream shader_stream;
|
||||||
|
shader_stream << file.rdbuf();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
code = shader_stream.str();
|
||||||
|
const char *code_charptr = code.c_str();
|
||||||
|
|
||||||
|
unsigned int shader = glCreateShader(type);
|
||||||
|
glShaderSource(shader, 1, &code_charptr, NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
checkCompileErrors(shader, "ANY");
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int ID;
|
unsigned int ID;
|
||||||
// constructor generates the shader on the fly
|
|
||||||
// ------------------------------------------------------------------------
|
Shader() : ID(glCreateProgram()) {
|
||||||
Shader(const char *vertexPath, const char *fragmentPath, const char *geometryPath = nullptr) {
|
}
|
||||||
// 1. retrieve the vertex/fragment source code from filePath
|
|
||||||
std::string vertexCode;
|
Shader(const char *vertex_path, const char *fragment_path, const char *geometry_path = nullptr) : Shader() {
|
||||||
std::string fragmentCode;
|
add_vertex_shader(vertex_path);
|
||||||
std::string geometryCode;
|
add_fragment_shader(fragment_path);
|
||||||
std::ifstream vShaderFile;
|
if (geometry_path) add_geometry_shader(geometry_path);
|
||||||
std::ifstream fShaderFile;
|
|
||||||
std::ifstream gShaderFile;
|
link();
|
||||||
// ensure ifstream objects can throw exceptions:
|
}
|
||||||
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
|
||||||
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
void add_vertex_shader(const char *path) {
|
||||||
gShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
unsigned int shader = load_shader(path, GL_VERTEX_SHADER);
|
||||||
try {
|
glAttachShader(ID, shader);
|
||||||
// open files
|
glDeleteShader(shader);
|
||||||
vShaderFile.open(vertexPath);
|
}
|
||||||
fShaderFile.open(fragmentPath);
|
|
||||||
std::stringstream vShaderStream, fShaderStream;
|
void add_fragment_shader(const char *path) {
|
||||||
// read file's buffer contents into streams
|
unsigned int shader = load_shader(path, GL_FRAGMENT_SHADER);
|
||||||
vShaderStream << vShaderFile.rdbuf();
|
glAttachShader(ID, shader);
|
||||||
fShaderStream << fShaderFile.rdbuf();
|
glDeleteShader(shader);
|
||||||
// close file handlers
|
}
|
||||||
vShaderFile.close();
|
|
||||||
fShaderFile.close();
|
void add_geometry_shader(const char *path) {
|
||||||
// convert stream into string
|
unsigned int shader = load_shader(path, GL_GEOMETRY_SHADER);
|
||||||
vertexCode = vShaderStream.str();
|
glAttachShader(ID, shader);
|
||||||
fragmentCode = fShaderStream.str();
|
glDeleteShader(shader);
|
||||||
// if geometry shader path is present, also load a geometry shader
|
}
|
||||||
if (geometryPath != nullptr) {
|
|
||||||
gShaderFile.open(geometryPath);
|
void add_transform_feedback(const char **varyings, size_t varying_count) {
|
||||||
std::stringstream gShaderStream;
|
for (size_t i = 0; i < varying_count; i++) { // TODO: Is this loop required?
|
||||||
gShaderStream << gShaderFile.rdbuf();
|
glTransformFeedbackVaryings(ID, varying_count, varyings, GL_INTERLEAVED_ATTRIBS);
|
||||||
gShaderFile.close();
|
|
||||||
geometryCode = gShaderStream.str();
|
|
||||||
}
|
|
||||||
} catch (std::ifstream::failure &e) {
|
|
||||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
|
||||||
}
|
}
|
||||||
const char *vShaderCode = vertexCode.c_str();
|
}
|
||||||
const char *fShaderCode = fragmentCode.c_str();
|
|
||||||
// 2. compile shaders
|
void link() {
|
||||||
unsigned int vertex, fragment;
|
|
||||||
// vertex shader
|
|
||||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
|
||||||
glCompileShader(vertex);
|
|
||||||
checkCompileErrors(vertex, "VERTEX");
|
|
||||||
// fragment Shader
|
|
||||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
|
||||||
glCompileShader(fragment);
|
|
||||||
checkCompileErrors(fragment, "FRAGMENT");
|
|
||||||
// if geometry shader is given, compile geometry shader
|
|
||||||
unsigned int geometry;
|
|
||||||
if (geometryPath != nullptr) {
|
|
||||||
const char *gShaderCode = geometryCode.c_str();
|
|
||||||
geometry = glCreateShader(GL_GEOMETRY_SHADER);
|
|
||||||
glShaderSource(geometry, 1, &gShaderCode, NULL);
|
|
||||||
glCompileShader(geometry);
|
|
||||||
checkCompileErrors(geometry, "GEOMETRY");
|
|
||||||
}
|
|
||||||
// shader Program
|
|
||||||
ID = glCreateProgram();
|
|
||||||
glAttachShader(ID, vertex);
|
|
||||||
glAttachShader(ID, fragment);
|
|
||||||
if (geometryPath != nullptr) glAttachShader(ID, geometry);
|
|
||||||
glLinkProgram(ID);
|
glLinkProgram(ID);
|
||||||
checkCompileErrors(ID, "PROGRAM");
|
checkCompileErrors(ID, "PROGRAM");
|
||||||
// delete the shaders as they're linked into our program now and no longer necessery
|
|
||||||
glDeleteShader(vertex);
|
|
||||||
glDeleteShader(fragment);
|
|
||||||
if (geometryPath != nullptr) glDeleteShader(geometry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// activate the shader
|
// activate the shader
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void use() {
|
void use() {
|
||||||
@ -101,51 +90,59 @@ class Shader {
|
|||||||
// utility uniform functions
|
// utility uniform functions
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setBool(const std::string &name, bool value) const {
|
void setBool(const std::string &name, bool value) const {
|
||||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
glUniform1i(getUniformLocation(name), (int)value);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setInt(const std::string &name, int value) const {
|
void setInt(const std::string &name, int value) const {
|
||||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
glUniform1i(getUniformLocation(name), value);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setFloat(const std::string &name, float value) const {
|
void setFloat(const std::string &name, float value) const {
|
||||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
glUniform1f(getUniformLocation(name), value);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setVec2(const std::string &name, const glm::vec2 &value) const {
|
void setVec2(const std::string &name, const glm::vec2 &value) const {
|
||||||
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
glUniform2fv(getUniformLocation(name), 1, &value[0]);
|
||||||
}
|
}
|
||||||
void setVec2(const std::string &name, float x, float y) const {
|
void setVec2(const std::string &name, float x, float y) const {
|
||||||
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
|
glUniform2f(getUniformLocation(name), x, y);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setVec3(const std::string &name, const glm::vec3 &value) const {
|
void setVec3(const std::string &name, const glm::vec3 &value) const {
|
||||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
glUniform3fv(getUniformLocation(name), 1, &value[0]);
|
||||||
}
|
}
|
||||||
void setVec3(const std::string &name, float x, float y, float z) const {
|
void setVec3(const std::string &name, float x, float y, float z) const {
|
||||||
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
glUniform3f(getUniformLocation(name), x, y, z);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setVec4(const std::string &name, const glm::vec4 &value) const {
|
void setVec4(const std::string &name, const glm::vec4 &value) const {
|
||||||
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
glUniform4fv(getUniformLocation(name), 1, &value[0]);
|
||||||
}
|
}
|
||||||
void setVec4(const std::string &name, float x, float y, float z, float w) {
|
void setVec4(const std::string &name, float x, float y, float z, float w) {
|
||||||
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
|
glUniform4f(getUniformLocation(name), x, y, z, w);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setMat2(const std::string &name, const glm::mat2 &mat) const {
|
void setMat2(const std::string &name, const glm::mat2 &mat) const {
|
||||||
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
glUniformMatrix2fv(getUniformLocation(name), 1, GL_FALSE, &mat[0][0]);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setMat3(const std::string &name, const glm::mat3 &mat) const {
|
void setMat3(const std::string &name, const glm::mat3 &mat) const {
|
||||||
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
glUniformMatrix3fv(getUniformLocation(name), 1, GL_FALSE, &mat[0][0]);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setMat4(const std::string &name, const glm::mat4 &mat) const {
|
void setMat4(const std::string &name, const glm::mat4 &mat) const {
|
||||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
glUniformMatrix4fv(getUniformLocation(name), 1, GL_FALSE, &mat[0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
GLint getUniformLocation(const std::string &name) const {
|
||||||
|
GLint location = glGetUniformLocation(ID, name.c_str());
|
||||||
|
if (location == -1) {
|
||||||
|
GG_CORE_ERROR("Invalid uniform location: " + name);
|
||||||
|
}
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
// utility function for checking shader compilation/linking errors.
|
// utility function for checking shader compilation/linking errors.
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void checkCompileErrors(GLuint shader, std::string type) {
|
void checkCompileErrors(GLuint shader, std::string type) {
|
||||||
|
@ -52,7 +52,7 @@ class Spatial {
|
|||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 get_matrix() {
|
glm::mat4 get_matrix() const {
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,4 +73,4 @@ class Spatial {
|
|||||||
glm::vec3 origin = glm::vec3(0.0f, 0.0f, 0.0f);
|
glm::vec3 origin = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace Gedeng
|
91
test/particle-demo/main.cpp
Normal file
91
test/particle-demo/main.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include "Gedeng/Logger.h"
|
||||||
|
#include "Gedeng/ParticleSystem.h"
|
||||||
|
#include "Gedeng/TextLabel.h"
|
||||||
|
#include "Gedeng/Vector3.h"
|
||||||
|
#define GEDENG_MAIN
|
||||||
|
#include <Gedeng.h>
|
||||||
|
|
||||||
|
class ParticleApp : public Gedeng::Application {
|
||||||
|
public:
|
||||||
|
ParticleApp(unsigned long ms_per_update, unsigned int window_size_x, unsigned int window_size_y,
|
||||||
|
Gedeng::String window_name)
|
||||||
|
: Application(ms_per_update, window_size_x, window_size_y, window_name),
|
||||||
|
camera(Gedeng::Camera(90, 1920, 1080, 0.1, 1000.0)),
|
||||||
|
albedo("Resources/Textures/PavingStones/PavingStones070_2K_Color.jpg", Gedeng::Texture::Settings()),
|
||||||
|
bump("Resources/Textures/PavingStones/PavingStones070_2K_Displacement.jpg", Gedeng::Texture::Settings()),
|
||||||
|
normal("Resources/Textures/PavingStones/PavingStones070_2K_Normal.jpg", Gedeng::Texture::Settings()) {
|
||||||
|
// Move and rotate the camera so we see the quad well
|
||||||
|
// camera.translate(glm::vec3(0.0, 0.0, -1.0));
|
||||||
|
// camera.rotate(180, glm::vec3(0.0, 1.0, 0.0));
|
||||||
|
|
||||||
|
particles.set_position(glm::vec3(0.0f, 0.0f, -5.0f));
|
||||||
|
particles.set_velocity(glm::vec3(-5, 0, -5), glm::vec3(5, 20, 5));
|
||||||
|
particles.set_gravity(glm::vec3(0, -5, 0));
|
||||||
|
particles.set_color(glm::vec3(0.0f, 0.5f, 1.0f));
|
||||||
|
particles.set_lifetime(1.5f, 3.0f);
|
||||||
|
particles.set_size(0.75f);
|
||||||
|
particles.set_interval(0.2f);
|
||||||
|
particles.set_number_of_particles(30);
|
||||||
|
particles.set_texture(&albedo);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ParticleApp() = default;
|
||||||
|
|
||||||
|
void fixed_update(double delta) override {
|
||||||
|
// camera.rotate(delta * 180, glm::vec3(0.0, 1.0, 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynamic_update(double delta) override {
|
||||||
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
/* render_shader.use();
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
render_shader.setMat4("projection", camera.get_projection());
|
||||||
|
render_shader.setMat4("view", camera.get_view());
|
||||||
|
render_shader.setVec3("viewPos", camera.get_translation());
|
||||||
|
|
||||||
|
// Lighting
|
||||||
|
render_shader.setVec3("lightPos", glm::vec3(0.0, 1.0, 5.0));
|
||||||
|
|
||||||
|
render_shader.setFloat("number_of_steps", glm::max(0.0f, number_of_steps));
|
||||||
|
render_shader.setFloat("number_of_refinement_steps", glm::max(0.0f, number_of_refinement_steps));
|
||||||
|
render_shader.setFloat("bump_depth", glm::max(0.0f, bump_depth));
|
||||||
|
|
||||||
|
// Textures
|
||||||
|
albedo.bind_to(0);
|
||||||
|
normal.bind_to(1);
|
||||||
|
bump.bind_to(2);
|
||||||
|
|
||||||
|
// Quad which is rendered onto
|
||||||
|
quad_mesh.rotate(delta * 25.0f, glm::normalize(glm::vec3(0.0, 0.0, 1.0)));
|
||||||
|
quad_mesh.render(render_shader);
|
||||||
|
|
||||||
|
debug_text.render_text(25.0f, 25.0f, 1.0f, Gedeng::Vector3(1.0, 1.0, 0.0)); */
|
||||||
|
|
||||||
|
particles.set_camera(camera);
|
||||||
|
particles.update(delta);
|
||||||
|
particles.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Gedeng::ParticleSystem particles;
|
||||||
|
|
||||||
|
Gedeng::VertexBuffer vertex_rectangle;
|
||||||
|
|
||||||
|
Gedeng::Camera camera;
|
||||||
|
|
||||||
|
Gedeng::Texture albedo;
|
||||||
|
Gedeng::Texture bump;
|
||||||
|
Gedeng::Texture normal;
|
||||||
|
|
||||||
|
Gedeng::QuadMesh quad_mesh;
|
||||||
|
|
||||||
|
Gedeng::TextLabel debug_text;
|
||||||
|
};
|
||||||
|
|
||||||
|
Gedeng::Application *Gedeng::create_application() {
|
||||||
|
GG_CLIENT_INFO("Creating Application");
|
||||||
|
return new ParticleApp(20, 1920, 1080, String("Parallax Demo"));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user