Merge branch 'Demos' into 'master'
Demos See merge request Mergul/bubel-ecs!8
This commit is contained in:
commit
3f01b96b76
60 changed files with 7079 additions and 1187 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -9,4 +9,5 @@
|
||||||
!skeleton.html
|
!skeleton.html
|
||||||
!meson.build
|
!meson.build
|
||||||
!meson_options.txt
|
!meson_options.txt
|
||||||
!compile_wasm.py
|
!compile_wasm.py
|
||||||
|
!compile_android.py
|
||||||
78
compile_android.py
Normal file
78
compile_android.py
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import os
|
||||||
|
import ntpath
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def compile(sources, output):
|
||||||
|
files = []
|
||||||
|
# r=root, d=directories, f = files
|
||||||
|
for path in sources:
|
||||||
|
for r, d, f in os.walk(path):
|
||||||
|
for file in f:
|
||||||
|
if ntpath.basename(file) != 'win_dll.d':
|
||||||
|
filename, file_extension = os.path.splitext(file)
|
||||||
|
if file_extension == '.d' and filename != 'package':
|
||||||
|
files.append(os.path.join(r, file))
|
||||||
|
|
||||||
|
ldc_path = 'ldc'
|
||||||
|
if 'LDC' in os.environ:
|
||||||
|
ldc_path = os.environ['LDC']
|
||||||
|
|
||||||
|
ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' '
|
||||||
|
|
||||||
|
for path in sources:
|
||||||
|
ldc_cmd += '-I' + path + ' '
|
||||||
|
|
||||||
|
for path in import_paths:
|
||||||
|
ldc_cmd += '-I' + path + ' '
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
ldc_cmd += f + ' '
|
||||||
|
|
||||||
|
print(ldc_cmd)
|
||||||
|
|
||||||
|
if os.system(ldc_cmd):
|
||||||
|
exit(0)
|
||||||
|
print()
|
||||||
|
|
||||||
|
clean = 0
|
||||||
|
ldc_flags = ''
|
||||||
|
import_paths = ['source','tests']
|
||||||
|
build_tests = 0
|
||||||
|
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if(arg == '-release'):
|
||||||
|
ldc_flags += '-release '
|
||||||
|
elif(arg == '-enable-inlining'):
|
||||||
|
ldc_flags += '-enable-inlining '
|
||||||
|
elif(arg == '-O3'):
|
||||||
|
ldc_flags += '-O3 '
|
||||||
|
elif(arg == '-O2'):
|
||||||
|
ldc_flags += '-O2 '
|
||||||
|
elif(arg == '-O1'):
|
||||||
|
ldc_flags += '-O1 '
|
||||||
|
elif(arg == '-O0'):
|
||||||
|
ldc_flags += '-O0 '
|
||||||
|
elif(arg == '-Os'):
|
||||||
|
ldc_flags += '-Os '
|
||||||
|
elif(arg == '-Oz'):
|
||||||
|
ldc_flags += '-Oz '
|
||||||
|
elif(arg == '-g'):
|
||||||
|
ldc_flags += '-g '
|
||||||
|
elif(arg == '-opt'):
|
||||||
|
ldc_flags += '-release -enable-inlining -O3 '
|
||||||
|
else:
|
||||||
|
print('unknown argument: ' + arg)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
compile(['source'], 'ecs.a')
|
||||||
|
|
||||||
|
#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/
|
||||||
|
CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang'
|
||||||
|
TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64'
|
||||||
|
SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm'
|
||||||
|
LDC_LIBS = ''#os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a'
|
||||||
|
|
||||||
|
os.system(CC + ' -Wl,-soname,libecs.so -shared --sysroot=' + SYSROOT + ' obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN +
|
||||||
|
' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \
|
||||||
|
-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \
|
||||||
|
-Wl,-z,now -mthumb -o libecs.so')
|
||||||
4
demos/.gitignore
vendored
4
demos/.gitignore
vendored
|
|
@ -14,4 +14,6 @@
|
||||||
!cimgui.bc
|
!cimgui.bc
|
||||||
!emscripten_shell.html
|
!emscripten_shell.html
|
||||||
!emscripten_multi_shell.html
|
!emscripten_multi_shell.html
|
||||||
.dub
|
!compile_android.py
|
||||||
|
.dub
|
||||||
|
Android
|
||||||
55
demos/assets/shaders/additive_particles.fp
Normal file
55
demos/assets/shaders/additive_particles.fp
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
precision mediump int;
|
||||||
|
precision mediump float;
|
||||||
|
precision lowp sampler2D;
|
||||||
|
precision lowp samplerCube;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GLES
|
||||||
|
#define TEX(x,y) texture2D(x,y)
|
||||||
|
#if __VERSION__ >290
|
||||||
|
#define M_IN in mediump
|
||||||
|
#define L_IN in lowp
|
||||||
|
#else
|
||||||
|
#define M_IN varying mediump
|
||||||
|
#define L_IN varying lowp
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define TEX(x,y) texture(x,y)
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
#define M_IN in
|
||||||
|
#define L_IN in
|
||||||
|
#else
|
||||||
|
#define M_IN varying
|
||||||
|
#define L_IN varying
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
M_IN vec2 uv;
|
||||||
|
M_IN vec4 color;
|
||||||
|
/*
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
in mediump vec2 uv;
|
||||||
|
#else
|
||||||
|
varying mediump vec2 uv;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
in vec2 uv;
|
||||||
|
#else
|
||||||
|
varying vec2 uv;
|
||||||
|
#endif
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
//layout(binding = 0)uniform sampler2D tex;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
//layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_FragColor = /*TEX(tex,uv) **/ color;
|
||||||
|
if(gl_FragColor.a < 0.01)discard;
|
||||||
|
}
|
||||||
106
demos/assets/shaders/additive_particles.vp
Normal file
106
demos/assets/shaders/additive_particles.vp
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
precision highp float;
|
||||||
|
precision highp int;
|
||||||
|
precision lowp sampler2D;
|
||||||
|
precision lowp samplerCube;
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
#define LOC(x) layout(location = x)
|
||||||
|
#define ATT in
|
||||||
|
#define M_OUT out mediump
|
||||||
|
#define L_OUT out lowp
|
||||||
|
#else
|
||||||
|
#define LOC(x)
|
||||||
|
#define ATT attribute
|
||||||
|
#define M_OUT varying mediump
|
||||||
|
#define L_OUT varying lowp
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
#define LOC(x) layout(location = x)
|
||||||
|
#define ATT in
|
||||||
|
#define M_OUT out
|
||||||
|
#define L_OUT out
|
||||||
|
#else
|
||||||
|
#define LOC(x)
|
||||||
|
#define ATT attribute
|
||||||
|
#define M_OUT varying
|
||||||
|
#define L_OUT varying
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 positions;
|
||||||
|
layout(location = 1) in vec2 tex_coords;
|
||||||
|
|
||||||
|
out mediump vec2 uv;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
attribute vec2 positions;
|
||||||
|
attribute vec2 tex_coords;
|
||||||
|
|
||||||
|
varying mediump vec2 uv;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 positions;
|
||||||
|
layout(location = 1) in vec2 tex_coords;
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
attribute vec2 positions;
|
||||||
|
attribute vec2 tex_coords;
|
||||||
|
|
||||||
|
varying vec2 uv;
|
||||||
|
#endif
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
#define VBO_BATCH 1
|
||||||
|
|
||||||
|
M_OUT vec2 uv;
|
||||||
|
L_OUT vec4 color;
|
||||||
|
|
||||||
|
LOC(0) ATT vec2 positions;
|
||||||
|
LOC(1) ATT vec2 tex_coords;
|
||||||
|
|
||||||
|
#ifdef VBO_BATCH
|
||||||
|
LOC(2) ATT float depth;
|
||||||
|
LOC(3) ATT vec4 vcolor;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
uniform vec4 vcolor;
|
||||||
|
|
||||||
|
float depth = matrix_2.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
#ifdef VBO_BATCH
|
||||||
|
vec3 position = vec3(positions*4.0,1.0);
|
||||||
|
uv = tex_coords;
|
||||||
|
#else
|
||||||
|
vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0);
|
||||||
|
uv = tex_coords * uv_transform.zw + uv_transform.xy;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
color = vcolor;
|
||||||
|
|
||||||
|
gl_Position = vec4(position.xy,depth,1.0);
|
||||||
|
|
||||||
|
}
|
||||||
64
demos/assets/shaders/circle.fp
Normal file
64
demos/assets/shaders/circle.fp
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
precision mediump int;
|
||||||
|
precision mediump float;
|
||||||
|
precision lowp sampler2D;
|
||||||
|
precision lowp samplerCube;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GLES
|
||||||
|
#define TEX(x,y) texture2D(x,y)
|
||||||
|
#if __VERSION__ >290
|
||||||
|
#define M_IN in mediump
|
||||||
|
#define L_IN in lowp
|
||||||
|
#else
|
||||||
|
#define M_IN varying mediump
|
||||||
|
#define L_IN varying lowp
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define TEX(x,y) texture(x,y)
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
#define M_IN in
|
||||||
|
#define L_IN in
|
||||||
|
#else
|
||||||
|
#define M_IN varying
|
||||||
|
#define L_IN varying
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
M_IN vec2 pos;
|
||||||
|
M_IN float edge;
|
||||||
|
//flat M_IN vec2 fpos;
|
||||||
|
|
||||||
|
//M_IN vec2 uv;
|
||||||
|
//M_IN vec4 color;
|
||||||
|
/*
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
in mediump vec2 uv;
|
||||||
|
#else
|
||||||
|
varying mediump vec2 uv;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
in vec2 uv;
|
||||||
|
#else
|
||||||
|
varying vec2 uv;
|
||||||
|
#endif
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
//layout(binding = 0)uniform sampler2D tex;
|
||||||
|
|
||||||
|
//uniform sampler2D tex;
|
||||||
|
|
||||||
|
//layout(location = 0) out vec4 outColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float len2 = dot(pos,pos);
|
||||||
|
|
||||||
|
if(len2 > 1.0)discard;
|
||||||
|
|
||||||
|
if(len2 > edge)gl_FragColor = vec4(0.4,0.8,1.0,0.8);//TEX(tex,uv) * color;
|
||||||
|
else gl_FragColor = vec4(0,0.6,1.0,0.35);//TEX(tex,uv) * color;
|
||||||
|
//gl_FragColor = vec4(pos,0,1);
|
||||||
|
//if(gl_FragColor.a < 0.01)discard;
|
||||||
|
}
|
||||||
114
demos/assets/shaders/circle.vp
Normal file
114
demos/assets/shaders/circle.vp
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
precision highp float;
|
||||||
|
precision highp int;
|
||||||
|
precision lowp sampler2D;
|
||||||
|
precision lowp samplerCube;
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
#define LOC(x) layout(location = x)
|
||||||
|
#define ATT in
|
||||||
|
#define M_OUT out mediump
|
||||||
|
#define L_OUT out lowp
|
||||||
|
#else
|
||||||
|
#define LOC(x)
|
||||||
|
#define ATT attribute
|
||||||
|
#define M_OUT varying mediump
|
||||||
|
#define L_OUT varying lowp
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
#define LOC(x) layout(location = x)
|
||||||
|
#define ATT in
|
||||||
|
#define M_OUT out
|
||||||
|
#define L_OUT out
|
||||||
|
#else
|
||||||
|
#define LOC(x)
|
||||||
|
#define ATT attribute
|
||||||
|
#define M_OUT varying
|
||||||
|
#define L_OUT varying
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
#ifdef GLES
|
||||||
|
#if __VERSION__ >290
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 positions;
|
||||||
|
layout(location = 1) in vec2 tex_coords;
|
||||||
|
|
||||||
|
out mediump vec2 uv;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
attribute vec2 positions;
|
||||||
|
attribute vec2 tex_coords;
|
||||||
|
|
||||||
|
varying mediump vec2 uv;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if __VERSION__ > 320
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
layout(location = 0) in vec2 positions;
|
||||||
|
layout(location = 1) in vec2 tex_coords;
|
||||||
|
|
||||||
|
out vec2 uv;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
uniform vec4 uv_transform;
|
||||||
|
|
||||||
|
attribute vec2 positions;
|
||||||
|
attribute vec2 tex_coords;
|
||||||
|
|
||||||
|
varying vec2 uv;
|
||||||
|
#endif
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
//#define VBO_BATCH 1
|
||||||
|
|
||||||
|
//M_OUT vec2 uv;
|
||||||
|
//L_OUT vec4 color;
|
||||||
|
M_OUT vec2 pos;
|
||||||
|
M_OUT float edge;
|
||||||
|
//flat M_OUT vec2 fpos;
|
||||||
|
|
||||||
|
LOC(0) ATT vec2 positions;
|
||||||
|
//LOC(1) ATT vec2 tex_coords;
|
||||||
|
|
||||||
|
#ifdef VBO_BATCH
|
||||||
|
LOC(2) ATT float depth;
|
||||||
|
LOC(3) ATT vec4 vcolor;
|
||||||
|
#else
|
||||||
|
uniform vec4 matrix_1;
|
||||||
|
uniform vec4 matrix_2;
|
||||||
|
//uniform vec4 uv_transform;
|
||||||
|
//uniform vec4 vcolor;
|
||||||
|
|
||||||
|
//float depth = matrix_2.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
//#ifdef VBO_BATCH
|
||||||
|
// vec3 position = vec3(positions*4.0,1.0);
|
||||||
|
// uv = tex_coords;
|
||||||
|
//#else
|
||||||
|
//edge = mix(0.1, 0.96, (matrix_2.z / 256));
|
||||||
|
edge = (matrix_1.w - matrix_2.z) / matrix_1.w;//matrix_2.z;//clamp((matrix_2,0.0,1.0);
|
||||||
|
edge *= edge;
|
||||||
|
pos = positions * 2.0;// / matrix_2.zw * 2;
|
||||||
|
//fpos = positions * matrix_2.xy;
|
||||||
|
vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0);
|
||||||
|
// uv = tex_coords * uv_transform.zw + uv_transform.xy;
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//color = vcolor * 2.0;
|
||||||
|
|
||||||
|
gl_Position = vec4(position.xy,0,1.0);
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 36 KiB |
91
demos/compile_android.py
Normal file
91
demos/compile_android.py
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
import os
|
||||||
|
import ntpath
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def compile(sources, output):
|
||||||
|
files = []
|
||||||
|
# r=root, d=directories, f = files
|
||||||
|
for path in sources:
|
||||||
|
for r, d, f in os.walk(path):
|
||||||
|
for file in f:
|
||||||
|
if ntpath.basename(file) != 'win_dll.d':
|
||||||
|
filename, file_extension = os.path.splitext(file)
|
||||||
|
if file_extension == '.d':
|
||||||
|
files.append(os.path.join(r, file))
|
||||||
|
|
||||||
|
ldc_path = 'ldc'
|
||||||
|
if 'LDC' in os.environ:
|
||||||
|
ldc_path = os.environ['LDC']
|
||||||
|
|
||||||
|
ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' '
|
||||||
|
|
||||||
|
for path in sources:
|
||||||
|
ldc_cmd += '-I' + path + ' '
|
||||||
|
|
||||||
|
for path in import_paths:
|
||||||
|
ldc_cmd += '-I' + path + ' '
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
ldc_cmd += f + ' '
|
||||||
|
|
||||||
|
print(ldc_cmd)
|
||||||
|
|
||||||
|
if os.system(ldc_cmd):
|
||||||
|
print('some kind of error')
|
||||||
|
exit(0)
|
||||||
|
print()
|
||||||
|
|
||||||
|
clean = 0
|
||||||
|
ldc_flags = '--d-version=SDL_209 --d-version=BindSDL_Image --d-version=MM_USE_POSIX_THREADS '
|
||||||
|
#import_paths = ['source','tests']
|
||||||
|
import_paths = ['external/android','external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source']
|
||||||
|
build_tests = 0
|
||||||
|
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if(arg == '-release'):
|
||||||
|
ldc_flags += '-release '
|
||||||
|
elif(arg == '-enable-inlining'):
|
||||||
|
ldc_flags += '-enable-inlining '
|
||||||
|
elif(arg == '-O3'):
|
||||||
|
ldc_flags += '-O3 '
|
||||||
|
elif(arg == '-O2'):
|
||||||
|
ldc_flags += '-O2 '
|
||||||
|
elif(arg == '-O1'):
|
||||||
|
ldc_flags += '-O1 '
|
||||||
|
elif(arg == '-O0'):
|
||||||
|
ldc_flags += '-O0 '
|
||||||
|
elif(arg == '-Os'):
|
||||||
|
ldc_flags += '-Os '
|
||||||
|
elif(arg == '-Oz'):
|
||||||
|
ldc_flags += '-Oz '
|
||||||
|
elif(arg == '-g'):
|
||||||
|
ldc_flags += '-g '
|
||||||
|
elif(arg == '-opt'):
|
||||||
|
ldc_flags += '-release -enable-inlining -O3 '
|
||||||
|
else:
|
||||||
|
print('unknown argument: ' + arg)
|
||||||
|
exit()
|
||||||
|
|
||||||
|
#compile(['source'], 'ecs.a')
|
||||||
|
compile(['external/wasm_imports/bindbc/sdl'], 'build/bindbc-sdl.a')
|
||||||
|
compile(['utils/source'], 'build/utils.a')
|
||||||
|
compile(['external/sources/mmutils'], 'build/mmutils.a')
|
||||||
|
compile(['external/sources/glad'], 'build/glad.a')
|
||||||
|
compile(['external/android/bindbc'], 'build/bindbc.a')
|
||||||
|
compile(['source'], 'build/demo.a')
|
||||||
|
|
||||||
|
#compile(['external/wasm_imports/bindbc/sdl','utils/source','external/sources/mmutils','external/sources/glad'], 'build/asd.a')
|
||||||
|
|
||||||
|
#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/
|
||||||
|
CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang'
|
||||||
|
TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64'
|
||||||
|
SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm'
|
||||||
|
#LDC_LIBS = os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a'
|
||||||
|
LDC_LIBS = ''
|
||||||
|
LIBS = '-L/platforms/android-21/arch-arm/usr/lib'
|
||||||
|
|
||||||
|
os.system(CC + ' -Wl,-soname,libdemos.so -shared --sysroot=' + SYSROOT + ' ../obj/*.o obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN +
|
||||||
|
' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \
|
||||||
|
-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \
|
||||||
|
-Wl,-z,now -mthumb -lm -lc -Llibs/armeabi-v7a -lcimgui -o libdemos.so')
|
||||||
|
|
||||||
|
|
@ -19,7 +19,8 @@
|
||||||
"libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"],
|
"libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"],
|
||||||
"lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"],
|
"lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"],
|
||||||
"dflags-ldc" : [
|
"dflags-ldc" : [
|
||||||
"--ffast-math"
|
"--ffast-math",
|
||||||
|
"-enable-cross-module-inlining"
|
||||||
],
|
],
|
||||||
"configurations" : [
|
"configurations" : [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
11
demos/external/android/bindbc/loader/package.d
vendored
Normal file
11
demos/external/android/bindbc/loader/package.d
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
// Copyright Michael D. Parker 2018.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
module bindbc.loader;
|
||||||
|
|
||||||
|
public
|
||||||
|
import bindbc.loader.sharedlib,
|
||||||
|
bindbc.loader.system;
|
||||||
282
demos/external/android/bindbc/loader/sharedlib.d
vendored
Normal file
282
demos/external/android/bindbc/loader/sharedlib.d
vendored
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
|
||||||
|
// Copyright Michael D. Parker 2018.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
module bindbc.loader.sharedlib;
|
||||||
|
|
||||||
|
import core.stdc.stdlib;
|
||||||
|
import core.stdc.string;
|
||||||
|
|
||||||
|
/// Handle to a shared library
|
||||||
|
struct SharedLib {
|
||||||
|
private void* _handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indicates an uninitialized or unassigned handle.
|
||||||
|
enum invalidHandle = SharedLib.init;
|
||||||
|
|
||||||
|
// Contains information about shared library and symbol load failures.
|
||||||
|
struct ErrorInfo {
|
||||||
|
private:
|
||||||
|
char[32] _error;
|
||||||
|
char[96] _message;
|
||||||
|
|
||||||
|
public @nogc nothrow @property:
|
||||||
|
/**
|
||||||
|
Returns the string "Missing Symbol" to indicate a symbol load failure, and
|
||||||
|
the name of a library to indicate a library load failure.
|
||||||
|
*/
|
||||||
|
const(char)* error() const { return _error.ptr; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a symbol name for symbol load failures, and a system-specific error
|
||||||
|
message for library load failures.
|
||||||
|
*/
|
||||||
|
const(char)* message() const { return _message.ptr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private {
|
||||||
|
__gshared ErrorInfo[] _errors;
|
||||||
|
__gshared size_t _errorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@nogc nothrow:
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns an slice containing all errors that have been accumulated by the
|
||||||
|
`load` and `bindSymbol` functions since the last call to `resetErrors`.
|
||||||
|
*/
|
||||||
|
const(ErrorInfo)[] errors()
|
||||||
|
{
|
||||||
|
return _errors[0 .. _errorCount];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the total number of errors that have been accumulated by the
|
||||||
|
`load` and `bindSymbol` functions since the last call to `resetErrors`.
|
||||||
|
*/
|
||||||
|
size_t errorCount()
|
||||||
|
{
|
||||||
|
return _errorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the error count to 0 and erases all accumulated errors. This function
|
||||||
|
does not release any memory allocated for the error list.
|
||||||
|
*/
|
||||||
|
void resetErrors()
|
||||||
|
{
|
||||||
|
_errorCount = 0;
|
||||||
|
memset(_errors.ptr, 0, _errors.length * ErrorInfo.sizeof);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void freeErrors()
|
||||||
|
{
|
||||||
|
free(_errors.ptr);
|
||||||
|
_errors.length = _errorCount = 0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Loads a symbol from a shared library and assigns it to a caller-supplied pointer.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
lib = a valid handle to a shared library loaded via the `load` function.
|
||||||
|
ptr = a pointer to a function or variable pointer whose declaration is
|
||||||
|
appropriate for the symbol being bound (it is up to the caller to
|
||||||
|
verify the types match).
|
||||||
|
symbolName = the name of the symbol to bind.
|
||||||
|
*/
|
||||||
|
void bindSymbol(SharedLib lib, void** ptr, const(char)* symbolName)
|
||||||
|
{
|
||||||
|
// Without this, DMD can hang in release builds
|
||||||
|
pragma(inline, false);
|
||||||
|
|
||||||
|
assert(lib._handle);
|
||||||
|
auto sym = loadSymbol(lib._handle, symbolName);
|
||||||
|
if(sym) {
|
||||||
|
*ptr = sym;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addErr("Missing Symbol", symbolName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Formats a symbol using the Windows stdcall mangling if necessary before passing it on to
|
||||||
|
bindSymbol.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
lib = a valid handle to a shared library loaded via the `load` function.
|
||||||
|
ptr = a pointer to a function or variable pointer whose declaration is
|
||||||
|
appropriate for the symbol being bound (it is up to the caller to
|
||||||
|
verify the types match).
|
||||||
|
symbolName = the name of the symbol to bind.
|
||||||
|
*/
|
||||||
|
void bindSymbol_stdcall(Func)(SharedLib lib, ref Func f, const(char)* symbolName)
|
||||||
|
{
|
||||||
|
import bindbc.loader.system : bindWindows, bind32;
|
||||||
|
|
||||||
|
static if(bindWindows && bind32) {
|
||||||
|
import core.stdc.stdio : snprintf;
|
||||||
|
import std.traits : ParameterTypeTuple;
|
||||||
|
|
||||||
|
uint paramSize(A...)(A args)
|
||||||
|
{
|
||||||
|
size_t sum = 0;
|
||||||
|
foreach(arg; args) {
|
||||||
|
sum += arg.sizeof;
|
||||||
|
|
||||||
|
// Align on 32-bit stack
|
||||||
|
if((sum & 3) != 0) {
|
||||||
|
sum += 4 - (sum & 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParameterTypeTuple!f params;
|
||||||
|
char[128] mangled;
|
||||||
|
snprintf(mangled.ptr, mangled.length, "_%s@%d", symbolName, paramSize(params));
|
||||||
|
symbolName = mangled.ptr;
|
||||||
|
}
|
||||||
|
bindSymbol(lib, cast(void**)&f, symbolName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Loads a shared library from disk, using the system-specific API and search rules.
|
||||||
|
|
||||||
|
libName = the name of the library to load. May include the full or relative
|
||||||
|
path for the file.
|
||||||
|
*/
|
||||||
|
SharedLib load(const(char)* libName)
|
||||||
|
{
|
||||||
|
auto handle = loadLib(libName);
|
||||||
|
if(handle) return SharedLib(handle);
|
||||||
|
else {
|
||||||
|
addErr(libName, null);
|
||||||
|
return invalidHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Unloads a shared library from process memory.
|
||||||
|
|
||||||
|
Generally, it is not necessary to call this function at program exit, as the system will ensure
|
||||||
|
any shared libraries loaded by the process will be unloaded then. However, any loaded shared
|
||||||
|
libraries that are no longer needed by the program during runtime, such as those that are part
|
||||||
|
of a "hot swap" mechanism, should be unloaded to free up resources.
|
||||||
|
*/
|
||||||
|
void unload(ref SharedLib lib) {
|
||||||
|
if(lib._handle) {
|
||||||
|
unloadLib(lib._handle);
|
||||||
|
lib = invalidHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void allocErrs() {
|
||||||
|
size_t newSize = _errorCount == 0 ? 16 : _errors.length * 2;
|
||||||
|
auto errs = cast(ErrorInfo*)malloc(ErrorInfo.sizeof * newSize);
|
||||||
|
if(!errs) exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
if(_errorCount > 0) {
|
||||||
|
memcpy(errs, _errors.ptr, ErrorInfo.sizeof * _errors.length);
|
||||||
|
free(_errors.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
_errors = errs[0 .. newSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
void addErr(const(char)* errstr, const(char)* message)
|
||||||
|
{
|
||||||
|
if(_errors.length == 0 || _errorCount >= _errors.length) {
|
||||||
|
allocErrs();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pinfo = &_errors[_errorCount];
|
||||||
|
strcpy(pinfo._error.ptr, errstr);
|
||||||
|
|
||||||
|
if(message) {
|
||||||
|
strncpy(pinfo._message.ptr, message, pinfo._message.length);
|
||||||
|
pinfo._message[pinfo._message.length - 1] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sysError(pinfo._message.ptr, pinfo._message.length);
|
||||||
|
}
|
||||||
|
++_errorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Windows)
|
||||||
|
{
|
||||||
|
import core.sys.windows.windows;
|
||||||
|
|
||||||
|
void* loadLib(const(char)* name)
|
||||||
|
{
|
||||||
|
return LoadLibraryA(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unloadLib(void* lib)
|
||||||
|
{
|
||||||
|
FreeLibrary(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* loadSymbol(void* lib, const(char)* symbolName)
|
||||||
|
{
|
||||||
|
return GetProcAddress(lib, symbolName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sysError(char* buf, size_t len)
|
||||||
|
{
|
||||||
|
char* msgBuf;
|
||||||
|
enum uint langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
||||||
|
|
||||||
|
FormatMessageA(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
null,
|
||||||
|
GetLastError(),
|
||||||
|
langID,
|
||||||
|
cast(char*)&msgBuf,
|
||||||
|
0,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
if(msgBuf) {
|
||||||
|
strncpy(buf, msgBuf, len);
|
||||||
|
buf[len - 1] = 0;
|
||||||
|
LocalFree(msgBuf);
|
||||||
|
}
|
||||||
|
else strncpy(buf, "Unknown Error\0", len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else version(Posix) {
|
||||||
|
import core.sys.posix.dlfcn;
|
||||||
|
|
||||||
|
void* loadLib(const(char)* name)
|
||||||
|
{
|
||||||
|
return dlopen(name, RTLD_NOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unloadLib(void* lib)
|
||||||
|
{
|
||||||
|
dlclose(lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* loadSymbol(void* lib, const(char)* symbolName)
|
||||||
|
{
|
||||||
|
return dlsym(lib, symbolName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sysError(char* buf, size_t len)
|
||||||
|
{
|
||||||
|
const (char)* msg = dlerror();
|
||||||
|
strncpy(buf, msg != null ? msg : "Unknown Error", len);
|
||||||
|
buf[len - 1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else static assert(0, "bindbc-loader is not implemented on this platform.");
|
||||||
55
demos/external/android/bindbc/loader/system.d
vendored
Normal file
55
demos/external/android/bindbc/loader/system.d
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
|
||||||
|
// Copyright Michael D. Parker 2018.
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
module bindbc.loader.system;
|
||||||
|
|
||||||
|
static if((void*).sizeof == 8) {
|
||||||
|
enum bind64 = true;
|
||||||
|
enum bind32 = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enum bind64 = false;
|
||||||
|
enum bind32 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Windows) enum bindWindows = true;
|
||||||
|
else enum bindWindows = false;
|
||||||
|
|
||||||
|
version(OSX) enum bindMac = true;
|
||||||
|
else enum bindMac = false;
|
||||||
|
|
||||||
|
version(linux) enum bindLinux = true;
|
||||||
|
else enum bindLinux = false;
|
||||||
|
|
||||||
|
version(Posix) enum bindPosix = true;
|
||||||
|
else enum bindPosix = false;
|
||||||
|
|
||||||
|
version(Android) enum bindAndroid = true;
|
||||||
|
else enum bindAndroid = false;
|
||||||
|
|
||||||
|
enum bindIOS = false;
|
||||||
|
enum bindWinRT = false;
|
||||||
|
|
||||||
|
version(FreeBSD) {
|
||||||
|
enum bindBSD = true;
|
||||||
|
enum bindFreeBSD = true;
|
||||||
|
enum bindOpenBSD = false;
|
||||||
|
}
|
||||||
|
else version(OpenBSD) {
|
||||||
|
enum bindBSD = true;
|
||||||
|
enum bindFreeBSD = false;
|
||||||
|
enum bindOpenBSD = true;
|
||||||
|
}
|
||||||
|
else version(BSD) {
|
||||||
|
enum bindBSD = true;
|
||||||
|
enum bindFreeBSD = false;
|
||||||
|
enum bindOpenBSD = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enum bindBSD = false;
|
||||||
|
enum bindFreeBSD = false;
|
||||||
|
enum bindOpenBSD = false;
|
||||||
|
}
|
||||||
10
demos/external/sources/cimgui/cimgui.d
vendored
10
demos/external/sources/cimgui/cimgui.d
vendored
|
|
@ -2,9 +2,17 @@
|
||||||
//based on imgui.h file version "1.73" from Dear ImGui https://github.com/ocornut/imgui
|
//based on imgui.h file version "1.73" from Dear ImGui https://github.com/ocornut/imgui
|
||||||
module cimgui.cimgui;
|
module cimgui.cimgui;
|
||||||
|
|
||||||
import core.stdc.stdarg;
|
// import core.stdc.stdarg;
|
||||||
//import core.stdc.stdio;
|
//import core.stdc.stdio;
|
||||||
|
|
||||||
|
version(WebAssembly)
|
||||||
|
{
|
||||||
|
alias va_list = char*;
|
||||||
|
pragma(LDC_va_start)
|
||||||
|
void va_start(T)(out va_list ap, ref T parmn) @nogc;
|
||||||
|
}
|
||||||
|
else import core.stdc.stdarg;
|
||||||
|
|
||||||
extern (C):
|
extern (C):
|
||||||
|
|
||||||
//alias ImU64 = ulong;
|
//alias ImU64 = ulong;
|
||||||
|
|
|
||||||
4
demos/external/sources/glad/gl/loader.d
vendored
4
demos/external/sources/glad/gl/loader.d
vendored
|
|
@ -35,14 +35,14 @@ bool open_gl() @nogc {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
version(OSX) {
|
version(OSX) {
|
||||||
enum const(char)*[] NAMES = [
|
enum const(char)*[4] NAMES = [
|
||||||
"../Frameworks/OpenGL.framework/OpenGL",
|
"../Frameworks/OpenGL.framework/OpenGL",
|
||||||
"/Library/Frameworks/OpenGL.framework/OpenGL",
|
"/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||||
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
|
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||||
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
|
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"];
|
enum const(char)*[2] NAMES = ["libGL.so.1", "libGL.so"];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(name; NAMES) {
|
foreach(name; NAMES) {
|
||||||
|
|
|
||||||
19
demos/external/sources/mmutils/thread_pool.d
vendored
19
demos/external/sources/mmutils/thread_pool.d
vendored
|
|
@ -201,6 +201,21 @@ void instructionPause()
|
||||||
static assert(0);
|
static assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else version (Android)
|
||||||
|
{
|
||||||
|
version(LDC)
|
||||||
|
{
|
||||||
|
import ldc.attributes;
|
||||||
|
@optStrategy("none")
|
||||||
|
static void nop()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
nop();
|
||||||
|
}
|
||||||
|
else static assert(0);
|
||||||
|
}
|
||||||
else version(WebAssembly)
|
else version(WebAssembly)
|
||||||
{
|
{
|
||||||
version(LDC)
|
version(LDC)
|
||||||
|
|
@ -381,8 +396,8 @@ version (MM_USE_POSIX_THREADS)
|
||||||
void start(DG dg)
|
void start(DG dg)
|
||||||
{
|
{
|
||||||
threadStart = dg;
|
threadStart = dg;
|
||||||
int ok = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
int err = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
||||||
if(!ok)handle = pthread_t();
|
if(err)handle = pthread_t();
|
||||||
//assert(ok == 0);
|
//assert(ok == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@
|
||||||
|
|
||||||
module bindbc.sdl.bind.sdllog;
|
module bindbc.sdl.bind.sdllog;
|
||||||
|
|
||||||
import core.stdc.stdarg : va_list;
|
version(WebAssembly)
|
||||||
|
{
|
||||||
|
alias va_list = char*;
|
||||||
|
}
|
||||||
|
else import core.stdc.stdarg : va_list;
|
||||||
import bindbc.sdl.config;
|
import bindbc.sdl.config;
|
||||||
|
|
||||||
enum SDL_MAX_LOG_MESSAGE = 4096;
|
enum SDL_MAX_LOG_MESSAGE = 4096;
|
||||||
|
|
|
||||||
12
demos/external/wasm_imports/bindbc/sdl/dynload.d
vendored
12
demos/external/wasm_imports/bindbc/sdl/dynload.d
vendored
|
|
@ -14,8 +14,8 @@ import bindbc.sdl.config,
|
||||||
bindbc.sdl.bind;
|
bindbc.sdl.bind;
|
||||||
|
|
||||||
private {
|
private {
|
||||||
SharedLib lib;
|
__gshared SharedLib lib;
|
||||||
SDLSupport loadedVersion;
|
__gshared SDLSupport loadedVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unloadSDL()
|
void unloadSDL()
|
||||||
|
|
@ -664,14 +664,14 @@ SDLSupport loadSDL(const(char)* libName)
|
||||||
lib.bindSymbol(cast(void**)&SDL_HasColorKey, "SDL_HasColorKey");
|
lib.bindSymbol(cast(void**)&SDL_HasColorKey, "SDL_HasColorKey");
|
||||||
lib.bindSymbol(cast(void**)&SDL_GetDisplayOrientation, "SDL_GetDisplayOrientation");
|
lib.bindSymbol(cast(void**)&SDL_GetDisplayOrientation, "SDL_GetDisplayOrientation");
|
||||||
|
|
||||||
version(linux) {
|
version(Android) {
|
||||||
lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority");
|
|
||||||
}
|
|
||||||
else version(Android) {
|
|
||||||
lib.bindSymbol(cast(void**)&SDL_IsChromebook, "SDL_IsChromebook");
|
lib.bindSymbol(cast(void**)&SDL_IsChromebook, "SDL_IsChromebook");
|
||||||
lib.bindSymbol(cast(void**)&SDL_IsDeXMode, "SDL_IsDeXMode");
|
lib.bindSymbol(cast(void**)&SDL_IsDeXMode, "SDL_IsDeXMode");
|
||||||
lib.bindSymbol(cast(void**)&SDL_AndroidBackButton, "SDL_AndroidBackButton");
|
lib.bindSymbol(cast(void**)&SDL_AndroidBackButton, "SDL_AndroidBackButton");
|
||||||
}
|
}
|
||||||
|
else version(linux) {
|
||||||
|
lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority");
|
||||||
|
}
|
||||||
|
|
||||||
if(errorCount() != errCount) return SDLSupport.badLibrary;
|
if(errorCount() != errCount) return SDLSupport.badLibrary;
|
||||||
else loadedVersion = SDLSupport.sdl209;
|
else loadedVersion = SDLSupport.sdl209;
|
||||||
|
|
|
||||||
|
|
@ -229,8 +229,8 @@ else {
|
||||||
}
|
}
|
||||||
|
|
||||||
private {
|
private {
|
||||||
SharedLib lib;
|
__gshared SharedLib lib;
|
||||||
SDLImageSupport loadedVersion;
|
__gshared SDLImageSupport loadedVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unloadSDLImage()
|
void unloadSDLImage()
|
||||||
|
|
|
||||||
BIN
demos/libs/armeabi-v7a/libcimgui.so
Executable file
BIN
demos/libs/armeabi-v7a/libcimgui.so
Executable file
Binary file not shown.
|
|
@ -4,10 +4,11 @@ import bindbc.sdl;
|
||||||
|
|
||||||
import cimgui.cimgui;
|
import cimgui.cimgui;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
import game_core.job_updater;
|
import game_core.job_updater;
|
||||||
|
|
||||||
import bubel.ecs.manager;
|
|
||||||
import bubel.ecs.core;
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.manager;
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
|
|
||||||
import ecs_utils.gfx.renderer;
|
import ecs_utils.gfx.renderer;
|
||||||
|
|
@ -21,6 +22,7 @@ import glad.gl.gles2;
|
||||||
import glad.gl.loader;
|
import glad.gl.loader;
|
||||||
|
|
||||||
import gui.manager;
|
import gui.manager;
|
||||||
|
import gui.tool_circle;
|
||||||
|
|
||||||
extern (C) :
|
extern (C) :
|
||||||
|
|
||||||
|
|
@ -39,6 +41,16 @@ struct Mouse
|
||||||
bool left, right, middle;
|
bool left, right, middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DemoCallbacks
|
||||||
|
{
|
||||||
|
void function() register;
|
||||||
|
void function() initialize;
|
||||||
|
void function() deinitialize;
|
||||||
|
bool function() loop;
|
||||||
|
void function(SDL_Event*) event;
|
||||||
|
const (char)* tips;
|
||||||
|
}
|
||||||
|
|
||||||
struct Launcher
|
struct Launcher
|
||||||
{
|
{
|
||||||
ECSJobUpdater* job_updater;
|
ECSJobUpdater* job_updater;
|
||||||
|
|
@ -47,10 +59,10 @@ struct Launcher
|
||||||
SDL_Window* window;
|
SDL_Window* window;
|
||||||
SDL_GLContext gl_context;
|
SDL_GLContext gl_context;
|
||||||
EntityManager* manager;
|
EntityManager* manager;
|
||||||
bool function() loop;
|
/*bool function() loop;
|
||||||
void function() end;
|
void function() end;
|
||||||
void function(SDL_Event*) event;
|
void function(SDL_Event*) event;*/
|
||||||
void function(vec2, Tool, int) tool;
|
//void function(vec2, Tool, int, bool) tool;
|
||||||
float scalling;
|
float scalling;
|
||||||
ivec2 window_size = ivec2(1024,768);
|
ivec2 window_size = ivec2(1024,768);
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
|
|
@ -65,15 +77,20 @@ struct Launcher
|
||||||
vec2 render_position;
|
vec2 render_position;
|
||||||
|
|
||||||
Tool used_tool;
|
Tool used_tool;
|
||||||
int tool_size = 0;
|
int tool_size = 100;
|
||||||
float tool_repeat = 0;
|
float tool_repeat = 0;
|
||||||
float repeat_time = 0;
|
float repeat_time = 0;
|
||||||
|
bool tool_show = true;
|
||||||
|
bool override_ = true;
|
||||||
|
bool tool_mode = true;
|
||||||
|
ToolCircle* tool_circle;
|
||||||
|
bool show_filtered;
|
||||||
|
|
||||||
bool swap_interval = true;
|
bool swap_interval = true;
|
||||||
|
|
||||||
float windows_alpha = 0.75;
|
float windows_alpha = 0.75;
|
||||||
|
|
||||||
const (char)* tips;
|
//const (char)* tips;
|
||||||
|
|
||||||
bool show_stat_wnd = true;
|
bool show_stat_wnd = true;
|
||||||
bool show_tips = true;
|
bool show_tips = true;
|
||||||
|
|
@ -93,17 +110,19 @@ struct Launcher
|
||||||
float draw_time = 0;
|
float draw_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, void function(vec2, Tool, int) tool, const (char)* tips)
|
DemoCallbacks demo;
|
||||||
|
|
||||||
|
void switchDemo(DemoCallbacks callbacks)//void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips)
|
||||||
{
|
{
|
||||||
gui_manager.clear();
|
gui_manager.clear();
|
||||||
//launcher.ent
|
//launcher.ent
|
||||||
|
|
||||||
if(this.end)this.end();
|
|
||||||
|
|
||||||
manager.begin();
|
manager.begin();
|
||||||
manager.update("clean");
|
manager.update("clean");
|
||||||
manager.end();
|
manager.end();
|
||||||
|
|
||||||
|
if(this.demo.deinitialize)this.demo.deinitialize();
|
||||||
|
|
||||||
foreach(ref system; manager.systems)
|
foreach(ref system; manager.systems)
|
||||||
{
|
{
|
||||||
if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable();
|
if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable();
|
||||||
|
|
@ -112,12 +131,154 @@ struct Launcher
|
||||||
/*launcher.manager.getSystem(CountSystem.system_id).enable();
|
/*launcher.manager.getSystem(CountSystem.system_id).enable();
|
||||||
launcher.manager.getSystem(CleanSystem.system_id).enable();//*/
|
launcher.manager.getSystem(CleanSystem.system_id).enable();//*/
|
||||||
|
|
||||||
if(start)start();
|
if(callbacks.register)callbacks.register();
|
||||||
this.loop = loop;
|
if(callbacks.initialize)callbacks.initialize();
|
||||||
|
demo = callbacks;
|
||||||
|
/*this.loop = loop;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.tips = tips;
|
this.tips = tips;*/
|
||||||
this.tool = tool;
|
//this.tool = tool;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filterEntity(ref const Entity entity)
|
||||||
|
{
|
||||||
|
EntityMeta meta = entity.getMeta();
|
||||||
|
foreach(id;gui_manager.filter_list)
|
||||||
|
{
|
||||||
|
if(!meta.hasComponent(id))return false;
|
||||||
|
}
|
||||||
|
if(used_tool == Tool.component_manipulator)
|
||||||
|
{
|
||||||
|
if(!meta.hasComponent(gui_manager.getSelectedComponent().component_id))return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void processTool(vec2 position, bool mode)
|
||||||
|
{
|
||||||
|
static struct Iterator
|
||||||
|
{
|
||||||
|
float size2;
|
||||||
|
vec2 position;
|
||||||
|
ComponentRef[] add_comps;
|
||||||
|
ushort[] rem_comps;
|
||||||
|
ushort[] filter;
|
||||||
|
|
||||||
|
bool filterEntity(ref const Entity entity)
|
||||||
|
{
|
||||||
|
EntityMeta meta = entity.getMeta();
|
||||||
|
foreach(id;filter)
|
||||||
|
{
|
||||||
|
if(!meta.hasComponent(id))return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEntity(IteratorSystem.EntitiesData data)
|
||||||
|
{
|
||||||
|
if(!filterEntity(data.entity[0]))return;
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
vec2 rel_vec = data.location[i] - position;
|
||||||
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
|
if(length < size2)gEM.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addComponent(IteratorSystem.EntitiesData data)
|
||||||
|
{
|
||||||
|
if(!filterEntity(data.entity[0]))return;
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
vec2 rel_vec = data.location[i] - position;
|
||||||
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
|
if(length < size2)gEM.addComponents(data.entity[i].id, add_comps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void overrideComponent(IteratorSystem.EntitiesData data)
|
||||||
|
{
|
||||||
|
if(!filterEntity(data.entity[0]))return;
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
vec2 rel_vec = data.location[i] - position;
|
||||||
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
|
if(length < size2)
|
||||||
|
{
|
||||||
|
gEM.removeComponents(data.entity[i].id, rem_comps);
|
||||||
|
gEM.addComponents(data.entity[i].id, add_comps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeComponent(IteratorSystem.EntitiesData data)
|
||||||
|
{
|
||||||
|
if(!filterEntity(data.entity[0]))return;
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
vec2 rel_vec = data.location[i] - position;
|
||||||
|
float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y;
|
||||||
|
if(length < size2)gEM.removeComponents(data.entity[i].id, rem_comps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float half_size = tool_size * 0.5;
|
||||||
|
float size2 = half_size * half_size;
|
||||||
|
Iterator iterator;
|
||||||
|
iterator.size2 = size2;
|
||||||
|
iterator.position = position;
|
||||||
|
iterator.filter = gui_manager.filter_list[];
|
||||||
|
|
||||||
|
switch(used_tool)
|
||||||
|
{
|
||||||
|
case Tool.entity_spawner:
|
||||||
|
if(mode)
|
||||||
|
{
|
||||||
|
if(gui_manager.templates.length == 0)return;
|
||||||
|
EntityTemplate* tmpl = gui_manager.getSelectedTemplate();
|
||||||
|
CLocation* location = tmpl.getComponent!CLocation;
|
||||||
|
if(location)
|
||||||
|
{
|
||||||
|
position += randomCircularSample() * half_size;
|
||||||
|
//if(position.y < 16)position.y = 16;
|
||||||
|
//else if(position.y > 299)position.y = 299;
|
||||||
|
*location = position;
|
||||||
|
}
|
||||||
|
manager.addEntity(tmpl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
manager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Tool.component_manipulator:
|
||||||
|
{
|
||||||
|
if(gui_manager.components.length == 0)return;
|
||||||
|
if(mode)
|
||||||
|
{
|
||||||
|
ComponentRef[1] comps = [gui_manager.getSelectedComponent()];
|
||||||
|
iterator.add_comps = comps;
|
||||||
|
if(launcher.override_)
|
||||||
|
{
|
||||||
|
ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id];
|
||||||
|
iterator.rem_comps = rcomps;
|
||||||
|
manager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent);
|
||||||
|
}
|
||||||
|
else manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ushort[1] comps = [gui_manager.getSelectedComponent().component_id];
|
||||||
|
iterator.rem_comps = comps;
|
||||||
|
manager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getKeyState(SDL_Scancode key)
|
bool getKeyState(SDL_Scancode key)
|
||||||
|
|
@ -184,6 +345,28 @@ struct CleanSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct IteratorSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!1;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
CLocation[] location;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mainLoop(void* arg)
|
void mainLoop(void* arg)
|
||||||
{
|
{
|
||||||
__gshared double time = 0;
|
__gshared double time = 0;
|
||||||
|
|
@ -203,18 +386,43 @@ void mainLoop(void* arg)
|
||||||
temp_fps = 0;
|
temp_fps = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event))
|
while (SDL_PollEvent(&event))
|
||||||
{
|
{
|
||||||
version(WebAssembly)ImGui_ImplSDL2_ProcessEvent(&event);
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
else ImGui_ImplSDL2_ProcessEvent(&event);
|
if(launcher.demo.event)launcher.demo.event(&event);
|
||||||
if(launcher.event)launcher.event(&event);
|
|
||||||
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) {
|
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) {
|
||||||
quit();
|
quit();
|
||||||
*cast(bool*)arg = false;
|
*cast(bool*)arg = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(event.type == SDL_KEYDOWN)
|
||||||
|
{
|
||||||
|
if(event.key.state)
|
||||||
|
{
|
||||||
|
if(SDL_GetModState() & KMOD_CTRL)
|
||||||
|
{
|
||||||
|
switch(event.key.keysym.scancode)
|
||||||
|
{
|
||||||
|
case SDL_SCANCODE_1:launcher.used_tool=Tool.entity_spawner;break;
|
||||||
|
case SDL_SCANCODE_2:launcher.used_tool=Tool.component_manipulator;break;
|
||||||
|
case SDL_SCANCODE_3:launcher.used_tool=Tool.selector;break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(event.key.keysym.scancode)
|
||||||
|
{
|
||||||
|
case SDL_SCANCODE_1:break;
|
||||||
|
case SDL_SCANCODE_2:break;
|
||||||
|
case SDL_SCANCODE_3:break;
|
||||||
|
case SDL_SCANCODE_4:break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(event.type == SDL_WINDOWEVENT)
|
else if(event.type == SDL_WINDOWEVENT)
|
||||||
{
|
{
|
||||||
switch(event.window.event)
|
switch(event.window.event)
|
||||||
|
|
@ -239,9 +447,12 @@ void mainLoop(void* arg)
|
||||||
case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break;
|
case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break;
|
||||||
default:break;
|
default:break;
|
||||||
}
|
}
|
||||||
if(launcher.tool && event.button.button == SDL_BUTTON_LEFT && launcher.tool_repeat == 0 && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
if(!igIsAnyItemHovered())igSetWindowFocus();
|
||||||
|
if(!igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow))
|
||||||
{
|
{
|
||||||
launcher.tool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position, launcher.used_tool, launcher.tool_size);
|
launcher.repeat_time = 0;
|
||||||
|
if(event.button.button == SDL_BUTTON_LEFT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,launcher.tool_mode);
|
||||||
|
else if(event.button.button == SDL_BUTTON_RIGHT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,!launcher.tool_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(event.type == SDL_MOUSEBUTTONUP)
|
else if(event.type == SDL_MOUSEBUTTONUP)
|
||||||
|
|
@ -257,17 +468,67 @@ void mainLoop(void* arg)
|
||||||
else if(event.type == SDL_MOUSEMOTION)
|
else if(event.type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y);
|
launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y);
|
||||||
|
}else if(event.type == SDL_MOUSEWHEEL)
|
||||||
|
{
|
||||||
|
if(!igIsAnyItemHovered() && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
||||||
|
{
|
||||||
|
if(SDL_GetModState() & KMOD_CTRL)
|
||||||
|
{
|
||||||
|
float sign = 1;
|
||||||
|
if(event.wheel.y < 0)sign = -1;
|
||||||
|
float val = /*sign * event.wheel.y */ launcher.tool_repeat * 0.25;
|
||||||
|
if(val < 0.1)val = 0.1;
|
||||||
|
launcher.tool_repeat -= sign * val;
|
||||||
|
if(launcher.tool_repeat < 0)launcher.tool_repeat = 0;
|
||||||
|
else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000;
|
||||||
|
}
|
||||||
|
else if(SDL_GetModState() & KMOD_SHIFT)
|
||||||
|
{
|
||||||
|
int sign = 1;
|
||||||
|
if(event.wheel.y < 0)sign = -1;
|
||||||
|
switch(launcher.used_tool)
|
||||||
|
{
|
||||||
|
case Tool.entity_spawner:
|
||||||
|
launcher.gui_manager.selectTemplate(launcher.gui_manager.selected_template-sign);
|
||||||
|
break;
|
||||||
|
case Tool.component_manipulator:
|
||||||
|
launcher.gui_manager.selectComponent(launcher.gui_manager.selected_component-sign);
|
||||||
|
break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int sign = 1;
|
||||||
|
if(event.wheel.y < 0)sign = -1;
|
||||||
|
int val = /*sign * event.wheel.y */ launcher.tool_size / 4;
|
||||||
|
if(val < 1)val = 1;
|
||||||
|
launcher.tool_size -= sign * val;
|
||||||
|
if(launcher.tool_size < 1)launcher.tool_size = 1;
|
||||||
|
else if(launcher.tool_size > 256)launcher.tool_size = 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow))
|
if(launcher.tool_repeat != 0 && (launcher.mouse.left || launcher.mouse.right) && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow))
|
||||||
{
|
{
|
||||||
|
bool mode = launcher.tool_mode;
|
||||||
|
if(launcher.mouse.right)mode = !mode;
|
||||||
float range = 500.0 / cast(float)launcher.tool_repeat;
|
float range = 500.0 / cast(float)launcher.tool_repeat;
|
||||||
launcher.repeat_time += launcher.delta_time;
|
launcher.repeat_time += launcher.delta_time;
|
||||||
while(launcher.repeat_time > range)
|
if(launcher.used_tool != Tool.entity_spawner || !mode)
|
||||||
{
|
{
|
||||||
launcher.repeat_time -= range;
|
if(launcher.repeat_time > range)launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode);
|
||||||
launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size);
|
while(launcher.repeat_time > range)launcher.repeat_time -= range;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(launcher.repeat_time > range)
|
||||||
|
{
|
||||||
|
launcher.repeat_time -= range;
|
||||||
|
launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,7 +539,8 @@ void mainLoop(void* arg)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImGuiImplOpenGL2NewFrame();
|
//ImGuiImplOpenGL2NewFrame();
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
ImGuiImplSDL2NewFrame(launcher.window);
|
ImGuiImplSDL2NewFrame(launcher.window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,17 +563,32 @@ void mainLoop(void* arg)
|
||||||
if(igMenuItemBool("Simpe",null,false,true))
|
if(igMenuItemBool("Simpe",null,false,true))
|
||||||
{
|
{
|
||||||
import demos.simple;
|
import demos.simple;
|
||||||
launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips);
|
launcher.switchDemo(getSimpleDemo());//&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips);
|
||||||
}
|
}
|
||||||
if(igMenuItemBool("Snake",null,false,true))
|
if(igMenuItemBool("Snake",null,false,true))
|
||||||
{
|
{
|
||||||
import demos.snake;
|
import demos.snake;
|
||||||
launcher.switchDemo(&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,&snakeTool,Snake.tips);
|
launcher.switchDemo(getSnakeDemo());//&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips);
|
||||||
}
|
}
|
||||||
if(igMenuItemBool("Space invaders",null,false,true))
|
if(igMenuItemBool("Space Invaders",null,false,true))
|
||||||
{
|
{
|
||||||
import demos.space_invaders;
|
import demos.space_invaders;
|
||||||
launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips);
|
launcher.switchDemo(getSpaceInvadersDemo());//&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips);
|
||||||
|
}
|
||||||
|
if(igMenuItemBool("Particles",null,false,true))
|
||||||
|
{
|
||||||
|
import demos.particles;
|
||||||
|
launcher.switchDemo(getParticlesDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips);
|
||||||
|
}
|
||||||
|
if(igMenuItemBool("Brick Breaker",null,false,true))
|
||||||
|
{
|
||||||
|
import demos.brick_breaker;
|
||||||
|
launcher.switchDemo(getBrickBreakerDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips);
|
||||||
|
}
|
||||||
|
if(igMenuItemBool("Sandbox",null,false,true))
|
||||||
|
{
|
||||||
|
import demos.sandbox;
|
||||||
|
launcher.switchDemo(getSanboxDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips);
|
||||||
}
|
}
|
||||||
igEndMenu();
|
igEndMenu();
|
||||||
}
|
}
|
||||||
|
|
@ -344,22 +621,11 @@ void mainLoop(void* arg)
|
||||||
}
|
}
|
||||||
if(igBeginMenu("Show",true))
|
if(igBeginMenu("Show",true))
|
||||||
{
|
{
|
||||||
if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true))
|
igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true);
|
||||||
{
|
igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true);
|
||||||
launcher.show_stat_wnd = !launcher.show_stat_wnd;
|
igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true);
|
||||||
}
|
igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true);
|
||||||
else if(igMenuItemBool("Demo",null,launcher.show_demo_wnd,true))
|
igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true);
|
||||||
{
|
|
||||||
launcher.show_demo_wnd = !launcher.show_demo_wnd;
|
|
||||||
}
|
|
||||||
else if(igMenuItemBool("Tips",null,launcher.show_tips,true))
|
|
||||||
{
|
|
||||||
launcher.show_tips = !launcher.show_tips;
|
|
||||||
}
|
|
||||||
else if(igMenuItemBool("Virual keys",null,launcher.show_virtual_keys_wnd,true))
|
|
||||||
{
|
|
||||||
launcher.show_virtual_keys_wnd = !launcher.show_virtual_keys_wnd;
|
|
||||||
}
|
|
||||||
igEndMenu();
|
igEndMenu();
|
||||||
}
|
}
|
||||||
if(igBeginMenu("Style",true))
|
if(igBeginMenu("Style",true))
|
||||||
|
|
@ -456,7 +722,7 @@ void mainLoop(void* arg)
|
||||||
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
||||||
if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings))
|
if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings))
|
||||||
{
|
{
|
||||||
igTextWrapped(launcher.tips);
|
igTextWrapped(launcher.demo.tips);
|
||||||
}
|
}
|
||||||
igEnd();
|
igEnd();
|
||||||
}
|
}
|
||||||
|
|
@ -464,20 +730,22 @@ void mainLoop(void* arg)
|
||||||
if(launcher.show_demo_wnd)
|
if(launcher.show_demo_wnd)
|
||||||
{
|
{
|
||||||
igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
||||||
igSetNextWindowSize(ImVec2(250, 500), ImGuiCond_Once);
|
igSetNextWindowSize(ImVec2(250, launcher.window_size.y - 60), ImGuiCond_Once);
|
||||||
if(igBegin("Demo",&launcher.show_demo_wnd,0))
|
if(igBegin("Demo",&launcher.show_demo_wnd,0))
|
||||||
{
|
{
|
||||||
ImDrawList* draw_list = igGetWindowDrawList();
|
ImDrawList* draw_list = igGetWindowDrawList();
|
||||||
//igBeginGroup();
|
igBeginGroup();
|
||||||
launcher.gui_manager.gui();
|
launcher.gui_manager.gui();
|
||||||
//igEndGroup();
|
igEndGroup();
|
||||||
|
ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1);
|
||||||
|
|
||||||
//ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1);
|
//ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1);
|
||||||
//igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow);
|
//igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow);
|
||||||
//igBeginChild("Tool frame",ImVec2(-1,-1),true,0);
|
//igBeginChild("Tool frame",ImVec2(-1,-1),true,0);
|
||||||
if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth))
|
igBeginGroup();
|
||||||
|
if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
igIndent(8);
|
igIndent(8);
|
||||||
igBeginGroup();
|
|
||||||
if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0))
|
if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0))
|
||||||
{
|
{
|
||||||
if(igSelectable("Entity spawner",false,0,ImVec2(0,0)))
|
if(igSelectable("Entity spawner",false,0,ImVec2(0,0)))
|
||||||
|
|
@ -494,14 +762,44 @@ void mainLoop(void* arg)
|
||||||
}
|
}
|
||||||
igEndCombo();
|
igEndCombo();
|
||||||
}
|
}
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)");
|
||||||
|
igCheckbox("Show Tool", &launcher.tool_show);
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation");
|
||||||
|
igSameLine(0,4);
|
||||||
|
igCheckbox("Show Filtered", &launcher.show_filtered);
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities");
|
||||||
|
if(launcher.used_tool == Tool.component_manipulator)
|
||||||
|
{
|
||||||
|
igCheckbox("Override", &launcher.override_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0));
|
||||||
|
if(launcher.used_tool != Tool.selector)
|
||||||
|
{
|
||||||
|
if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true;
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)");
|
||||||
|
igSameLine(0,4);
|
||||||
|
if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false;
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)");
|
||||||
|
}
|
||||||
|
|
||||||
igSliderInt("Tool size", &launcher.tool_size, 0, 256, null);
|
igSliderInt("Tool size", &launcher.tool_size, 0, 256, null);
|
||||||
igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4);
|
igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4);
|
||||||
launcher.gui_manager.toolGui();
|
launcher.gui_manager.toolGui();
|
||||||
igEndGroup();
|
|
||||||
ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1);
|
|
||||||
igUnindent(8);
|
igUnindent(8);
|
||||||
}
|
}
|
||||||
|
igEndGroup();
|
||||||
|
ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1);
|
||||||
|
|
||||||
|
//igBeginGroup();
|
||||||
|
if(igCollapsingHeader("Filter", ImGuiTreeNodeFlags_SpanAvailWidth))
|
||||||
|
{
|
||||||
|
igIndent(8);
|
||||||
|
launcher.gui_manager.filterGUI();
|
||||||
|
igUnindent(8);
|
||||||
|
}
|
||||||
|
//igEndGroup();
|
||||||
|
//ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1);
|
||||||
|
|
||||||
//igEndChild();
|
//igEndChild();
|
||||||
//igEndChildFrame();
|
//igEndChildFrame();
|
||||||
|
|
@ -517,7 +815,8 @@ void mainLoop(void* arg)
|
||||||
|
|
||||||
if(launcher.show_profile_wnd)
|
if(launcher.show_profile_wnd)
|
||||||
{
|
{
|
||||||
igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0));
|
//igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0));
|
||||||
|
igSetNextWindowPos(ImVec2(8, launcher.window_size.y - 258), ImGuiCond_Once, ImVec2(0,0));
|
||||||
igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once);
|
igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once);
|
||||||
if(igBegin("Profile",&launcher.show_profile_wnd,0))
|
if(igBegin("Profile",&launcher.show_profile_wnd,0))
|
||||||
{
|
{
|
||||||
|
|
@ -565,7 +864,7 @@ void mainLoop(void* arg)
|
||||||
|
|
||||||
double loop_time = launcher.getTime();
|
double loop_time = launcher.getTime();
|
||||||
launcher.job_updater.pool.tryWaitCount = 10000;
|
launcher.job_updater.pool.tryWaitCount = 10000;
|
||||||
if(launcher.loop && !launcher.loop())
|
if(launcher.demo.loop && !launcher.demo.loop())
|
||||||
{
|
{
|
||||||
quit();
|
quit();
|
||||||
*cast(bool*)arg = false;
|
*cast(bool*)arg = false;
|
||||||
|
|
@ -578,6 +877,8 @@ void mainLoop(void* arg)
|
||||||
launcher.renderer.present();
|
launcher.renderer.present();
|
||||||
draw_time = launcher.getTime() - draw_time;
|
draw_time = launcher.getTime() - draw_time;
|
||||||
|
|
||||||
|
if(launcher.tool_show)launcher.tool_circle.draw(&launcher.renderer, (launcher.mouse.position*launcher.scalling)-launcher.render_position, cast(float)launcher.tool_size, launcher.renderer.view_size.y*6*launcher.scalling);
|
||||||
|
|
||||||
__gshared float plot_time = 0;
|
__gshared float plot_time = 0;
|
||||||
__gshared uint plot_samples = 0;
|
__gshared uint plot_samples = 0;
|
||||||
plot_time += launcher.delta_time;
|
plot_time += launcher.delta_time;
|
||||||
|
|
@ -632,7 +933,9 @@ void mainLoop(void* arg)
|
||||||
|
|
||||||
igRender();
|
igRender();
|
||||||
version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
||||||
else ImGuiImplOpenGL2RenderDrawData(igGetDrawData());
|
else version(Android)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
||||||
|
else ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData());
|
||||||
|
//ImGuiImplOpenGL2RenderDrawData(igGetDrawData());
|
||||||
|
|
||||||
//launcher.renderer.clear();
|
//launcher.renderer.clear();
|
||||||
//launcher.renderer.present();
|
//launcher.renderer.present();
|
||||||
|
|
@ -643,24 +946,64 @@ void mainLoop(void* arg)
|
||||||
|
|
||||||
void quit()
|
void quit()
|
||||||
{
|
{
|
||||||
|
import game_core.rendering : TexCoordsManager;
|
||||||
launcher.gui_manager.clear();
|
launcher.gui_manager.clear();
|
||||||
Mallocator.dispose(launcher.gui_manager);
|
Mallocator.dispose(launcher.gui_manager);
|
||||||
|
|
||||||
|
if(launcher.demo.deinitialize)launcher.demo.deinitialize();
|
||||||
|
|
||||||
launcher.manager.destroy();
|
launcher.manager.destroy();
|
||||||
launcher.manager = null;
|
launcher.manager = null;
|
||||||
|
|
||||||
|
TexCoordsManager.destroy();
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
version(WebAssembly)emscripten_cancel_main_loop();
|
version(WebAssembly)emscripten_cancel_main_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
version(Android)
|
||||||
{
|
{
|
||||||
|
export extern (C) int SDL_main(int argc, char** args)
|
||||||
|
{
|
||||||
|
return app_main(argc,args);
|
||||||
|
}
|
||||||
|
|
||||||
|
import ldc.attributes;
|
||||||
|
|
||||||
|
extern (C) __gshared
|
||||||
|
{
|
||||||
|
@section(".tdata")
|
||||||
|
int _tlsstart = 0;
|
||||||
|
@section(".tcommon")
|
||||||
|
int _tlsend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
extern (C) int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
return app_main(argc,argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int app_main(int argc, char** argv)
|
||||||
|
//int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
|
||||||
|
version(BindSDL_Static){}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadSDL();
|
||||||
|
loadSDLImage();
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
{
|
{
|
||||||
printf("SDL could not initialize! SDL_Error: %s", SDL_GetError());
|
printf("SDL could not initialize! SDL_Error: %s", SDL_GetError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_version sdl_version;
|
SDL_version sdl_version;
|
||||||
SDL_GetVersion(&sdl_version);
|
SDL_GetVersion(&sdl_version);
|
||||||
printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch);
|
printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch);
|
||||||
|
|
@ -669,6 +1012,7 @@ int main(int argc, char** argv)
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED,
|
launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED,
|
||||||
SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
|
SDL_MaximizeWindow(launcher.window);
|
||||||
|
|
||||||
launcher.gl_context = SDL_GL_CreateContext(launcher.window);
|
launcher.gl_context = SDL_GL_CreateContext(launcher.window);
|
||||||
launcher.context = igCreateContext(null);
|
launcher.context = igCreateContext(null);
|
||||||
|
|
@ -692,6 +1036,21 @@ int main(int argc, char** argv)
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else version(Android)
|
||||||
|
{
|
||||||
|
//gladLoadGL();
|
||||||
|
gladLoadGLES2(x => SDL_GL_GetProcAddress(x));
|
||||||
|
if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context))
|
||||||
|
{
|
||||||
|
printf("ImGui initialization failed!");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
if(!ImGui_ImplOpenGL3_Init("#version 100"))
|
||||||
|
{
|
||||||
|
printf("ImGui OpenGL initialization failed!");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gladLoadGL();
|
gladLoadGL();
|
||||||
|
|
@ -700,17 +1059,19 @@ int main(int argc, char** argv)
|
||||||
printf("ImGui initialization failed!");
|
printf("ImGui initialization failed!");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if(!ImGuiImplOpenGL2Init())
|
//if(!ImGuiImplOpenGL2Init())
|
||||||
|
if(!ImGui_ImplOpenGL3_Init("#version 120"))
|
||||||
{
|
{
|
||||||
printf("ImGui OpenGL initialization failed!");
|
printf("ImGui OpenGL initialization failed!");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImFontConfig* config = ImFontConfig_ImFontConfig();
|
//ImFontConfig* config = ImFontConfig_ImFontConfig();
|
||||||
ImGuiIO* io = igGetIO();
|
ImGuiIO* io = igGetIO();
|
||||||
const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts);
|
const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts);
|
||||||
ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, config, font_ranges);
|
ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, null, font_ranges);
|
||||||
|
//ImFontConfig_destroy(config);
|
||||||
|
|
||||||
setStyle(3);
|
setStyle(3);
|
||||||
|
|
||||||
|
|
@ -728,14 +1089,19 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
launcher.manager.registerPass("clean");
|
launcher.manager.registerPass("clean");
|
||||||
|
|
||||||
|
launcher.manager.registerComponent!CLocation;
|
||||||
|
|
||||||
launcher.manager.registerSystem!CountSystem(10000);
|
launcher.manager.registerSystem!CountSystem(10000);
|
||||||
launcher.manager.registerSystem!CleanSystem(0,"clean");
|
launcher.manager.registerSystem!CleanSystem(0,"clean");
|
||||||
|
launcher.manager.registerSystem!IteratorSystem(0,"clean");
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
launcher.manager.endRegister();
|
||||||
|
|
||||||
loadGFX();
|
loadGFX();
|
||||||
|
|
||||||
launcher.renderer.initialize();
|
launcher.renderer.initialize();
|
||||||
|
import game_core.rendering : TexCoordsManager;
|
||||||
|
TexCoordsManager.initialize();
|
||||||
|
|
||||||
import mmutils.thread_pool : ThreadPool;
|
import mmutils.thread_pool : ThreadPool;
|
||||||
launcher.threads = ThreadPool.getCPUCoresCount();
|
launcher.threads = ThreadPool.getCPUCoresCount();
|
||||||
|
|
@ -746,8 +1112,14 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
import demos.simple;
|
import demos.simple;
|
||||||
import demos.space_invaders;
|
import demos.space_invaders;
|
||||||
// launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips);
|
import demos.particles;
|
||||||
launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips);
|
import demos.brick_breaker;
|
||||||
|
// launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips);
|
||||||
|
// launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips);
|
||||||
|
// launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips);
|
||||||
|
// launcher.switchDemo(getParticlesDemo());
|
||||||
|
// launcher.switchDemo(getSimpleDemo());
|
||||||
|
launcher.switchDemo(getBrickBreakerDemo());
|
||||||
}
|
}
|
||||||
|
|
||||||
int key_num;
|
int key_num;
|
||||||
|
|
@ -775,8 +1147,6 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityManager.destroy();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -792,7 +1162,7 @@ void loadGFX()
|
||||||
Texture.__loadBackend();
|
Texture.__loadBackend();
|
||||||
Renderer.__loadBackend();
|
Renderer.__loadBackend();
|
||||||
|
|
||||||
GfxConfig.materials = Mallocator.makeArray!Material(1);
|
GfxConfig.materials = Mallocator.makeArray!Material(3);
|
||||||
GfxConfig.meshes = Mallocator.makeArray!Mesh(1);
|
GfxConfig.meshes = Mallocator.makeArray!Mesh(1);
|
||||||
|
|
||||||
float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0];
|
float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0];
|
||||||
|
|
@ -839,7 +1209,93 @@ void loadGFX()
|
||||||
GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex");
|
GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex");
|
||||||
|
|
||||||
|
|
||||||
|
Shader vsh2;
|
||||||
|
vsh2.create();
|
||||||
|
vsh2.load("assets/shaders/circle.vp");
|
||||||
|
vsh2.compile();
|
||||||
|
|
||||||
|
Shader fsh2;
|
||||||
|
fsh2.create();
|
||||||
|
fsh2.load("assets/shaders/circle.fp");
|
||||||
|
fsh2.compile();
|
||||||
|
|
||||||
|
GfxConfig.materials[1].create();
|
||||||
|
GfxConfig.materials[1].data.blend_mode = Material.BlendMode.mixed;
|
||||||
|
GfxConfig.materials[1].data.mode = Material.TransformMode.position;
|
||||||
|
Material.ShaderModule[1] modules2 = [Material.ShaderModule(vsh2,fsh2)];
|
||||||
|
GfxConfig.materials[1].attachModules(modules2);
|
||||||
|
//GfxConfig.materials[0].
|
||||||
|
//GfxConfig.materials[0].load(load_data.materials[i].str);
|
||||||
|
GfxConfig.materials[1].compile();
|
||||||
|
GfxConfig.materials[1].bindAttribLocation("positions",0);
|
||||||
|
//GfxConfig.materials[1].bindAttribLocation("tex_coords",1);
|
||||||
|
//GfxConfig.materials[1].bindAttribLocation("depth",2);
|
||||||
|
//GfxConfig.materials[1].bindAttribLocation("vcolor",3);
|
||||||
|
GfxConfig.materials[1].link();
|
||||||
|
|
||||||
|
/* import std.stdio;
|
||||||
|
writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions"));
|
||||||
|
writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords"));
|
||||||
|
writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth"));
|
||||||
|
writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/
|
||||||
|
|
||||||
|
GfxConfig.materials[1].data.uniforms = Mallocator.makeArray!(Material.Uniform)(2);
|
||||||
|
GfxConfig.materials[1].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_1"), 0);
|
||||||
|
GfxConfig.materials[1].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_2"), 16);
|
||||||
|
//GfxConfig.materials[1].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32);
|
||||||
|
//GfxConfig.materials[1].data.bindings = Mallocator.makeArray!(int)(1);
|
||||||
|
//GfxConfig.materials[1].data.bindings[0] = GfxConfig.materials[0].getLocation("tex");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Shader vsh3;
|
||||||
|
vsh3.create();
|
||||||
|
vsh3.load("assets/shaders/additive_particles.vp");
|
||||||
|
vsh3.compile();
|
||||||
|
|
||||||
|
Shader fsh3;
|
||||||
|
fsh3.create();
|
||||||
|
fsh3.load("assets/shaders/additive_particles.fp");
|
||||||
|
fsh3.compile();
|
||||||
|
|
||||||
|
GfxConfig.materials[2].create();
|
||||||
|
GfxConfig.materials[2].data.blend_mode = Material.BlendMode.opaque;
|
||||||
|
GfxConfig.materials[2].data.mode = Material.TransformMode.position;
|
||||||
|
Material.ShaderModule[1] modules3 = [Material.ShaderModule(vsh3,fsh3)];
|
||||||
|
GfxConfig.materials[2].attachModules(modules3);
|
||||||
|
//GfxConfig.materials[0].
|
||||||
|
//GfxConfig.materials[0].load(load_data.materials[i].str);
|
||||||
|
GfxConfig.materials[2].compile();
|
||||||
|
GfxConfig.materials[2].bindAttribLocation("positions",0);
|
||||||
|
GfxConfig.materials[2].bindAttribLocation("tex_coords",1);
|
||||||
|
GfxConfig.materials[2].bindAttribLocation("depth",2);
|
||||||
|
GfxConfig.materials[2].bindAttribLocation("vcolor",3);
|
||||||
|
GfxConfig.materials[2].link();
|
||||||
|
|
||||||
|
/* import std.stdio;
|
||||||
|
writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions"));
|
||||||
|
writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords"));
|
||||||
|
writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth"));
|
||||||
|
writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/
|
||||||
|
|
||||||
|
GfxConfig.materials[2].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3);
|
||||||
|
GfxConfig.materials[2].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0);
|
||||||
|
GfxConfig.materials[2].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16);
|
||||||
|
GfxConfig.materials[2].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32);
|
||||||
|
GfxConfig.materials[2].data.bindings = Mallocator.makeArray!(int)(1);
|
||||||
|
GfxConfig.materials[2].data.bindings[0] = GfxConfig.materials[0].getLocation("tex");
|
||||||
|
GfxConfig.materials[2].data.blend_mode = Material.BlendMode.additive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*glUseProgram(0);
|
/*glUseProgram(0);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/
|
||||||
|
|
||||||
|
launcher.tool_circle = Mallocator.make!ToolCircle;
|
||||||
}
|
}
|
||||||
501
demos/source/demos/brick_breaker.d
Normal file
501
demos/source/demos/brick_breaker.d
Normal file
|
|
@ -0,0 +1,501 @@
|
||||||
|
module demos.brick_breaker;
|
||||||
|
|
||||||
|
import app;
|
||||||
|
|
||||||
|
import bindbc.sdl;
|
||||||
|
|
||||||
|
import bubel.ecs.attributes;
|
||||||
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.entity;
|
||||||
|
import bubel.ecs.manager;
|
||||||
|
import bubel.ecs.std;
|
||||||
|
|
||||||
|
import cimgui.cimgui;
|
||||||
|
|
||||||
|
import ecs_utils.gfx.texture;
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
import ecs_utils.utils;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
|
import game_core.rendering;
|
||||||
|
import game_core.collision;
|
||||||
|
|
||||||
|
extern(C):
|
||||||
|
|
||||||
|
private enum float px = 1.0/512.0;
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Components ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
/*struct CLocation
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias location this;
|
||||||
|
|
||||||
|
vec2 location;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
struct CBrick
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CPaddle
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CBall
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
ubyte radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CHitPoints
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
short value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct CVelocityFactor
|
||||||
|
// {
|
||||||
|
// mixin ECS.Component;
|
||||||
|
|
||||||
|
// alias value this;
|
||||||
|
|
||||||
|
// vec2 value = vec2(1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// struct CVelocity
|
||||||
|
// {
|
||||||
|
// mixin ECS.Component;
|
||||||
|
|
||||||
|
// alias value this;
|
||||||
|
|
||||||
|
// vec2 value = vec2(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct EDamage
|
||||||
|
{
|
||||||
|
mixin ECS.Event;
|
||||||
|
|
||||||
|
ubyte damage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
// struct MoveSystem
|
||||||
|
// {
|
||||||
|
// mixin ECS.System!64;
|
||||||
|
|
||||||
|
// struct EntitiesData
|
||||||
|
// {
|
||||||
|
// uint length;
|
||||||
|
// CLocation[] location;
|
||||||
|
// @readonly CVelocity[] velocity;
|
||||||
|
// @optional @readonly CVelocityFactor[] vel_factor;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void onUpdate(EntitiesData data)
|
||||||
|
// {
|
||||||
|
// if(data.vel_factor)
|
||||||
|
// {
|
||||||
|
// foreach(i; 0..data.length)
|
||||||
|
// {
|
||||||
|
// data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// foreach(i; 0..data.length)
|
||||||
|
// {
|
||||||
|
// data.location[i] += data.velocity[i] * launcher.delta_time;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct EdgeCollisionSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
CLocation[] location;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
//CBall[] ball_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
if(data.location[i].x < 0)
|
||||||
|
{
|
||||||
|
if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x;
|
||||||
|
data.location[i].x = 0;
|
||||||
|
}
|
||||||
|
else if(data.location[i].x > 400)
|
||||||
|
{
|
||||||
|
if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x;
|
||||||
|
data.location[i].x = 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data.location[i].y < 0)
|
||||||
|
{
|
||||||
|
if(data.velocity[i].y < 0)data.velocity[i].y = -data.velocity[i].y;
|
||||||
|
data.location[i].y = 0;
|
||||||
|
}
|
||||||
|
else if(data.location[i].y > 300)
|
||||||
|
{
|
||||||
|
if(data.velocity[i].y > 0)data.velocity[i].y = -data.velocity[i].y;
|
||||||
|
data.location[i].y = 300;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BallCollisionSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
mixin ECS.ReadOnlyDependencies!(ShootGridDependency, BVHDependency);
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
///variable named "length" contain entites count
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
@readonly CLocation[] location;
|
||||||
|
@readonly CScale[] scale;
|
||||||
|
@readonly CBall[] ball_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
bool test(EntityID id)
|
||||||
|
{
|
||||||
|
Entity* entity = launcher.manager.getEntity(id);
|
||||||
|
if(entity)
|
||||||
|
{
|
||||||
|
CLocation* location = entity.getComponent!CLocation;
|
||||||
|
CScale* scale = entity.getComponent!CScale;
|
||||||
|
if(location && scale)
|
||||||
|
{
|
||||||
|
float radius = data.scale[i].x;
|
||||||
|
vec2 rel_pos = *location - data.location[i];
|
||||||
|
vec2 abs_rel_pos = rel_pos;
|
||||||
|
if(abs_rel_pos.x < 0)abs_rel_pos.x = -abs_rel_pos.x;
|
||||||
|
if(abs_rel_pos.y < 0)abs_rel_pos.y = -abs_rel_pos.y;
|
||||||
|
|
||||||
|
vec2 half_scale = *scale * 0.25f;
|
||||||
|
|
||||||
|
if(abs_rel_pos.x < half_scale.x + radius &&
|
||||||
|
abs_rel_pos.y < half_scale.y + radius)
|
||||||
|
{
|
||||||
|
if(abs_rel_pos.x < half_scale.x)
|
||||||
|
{
|
||||||
|
if(rel_pos.y * data.velocity[i].y > 0)
|
||||||
|
{
|
||||||
|
data.velocity[i].y = -data.velocity[i].y;
|
||||||
|
launcher.manager.sendEvent(id,EDamage(1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(abs_rel_pos.y < half_scale.y)
|
||||||
|
{
|
||||||
|
if(rel_pos.x * data.velocity[i].x > 0)
|
||||||
|
{
|
||||||
|
data.velocity[i].x = -data.velocity[i].x;
|
||||||
|
launcher.manager.sendEvent(id,EDamage(1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec2 vector = abs_rel_pos - half_scale;
|
||||||
|
if(rel_pos.x > 0)vector.x = -vector.x;
|
||||||
|
if(rel_pos.y > 0)vector.y = -vector.y;
|
||||||
|
|
||||||
|
float pow_dist = vector.length2();
|
||||||
|
if(pow_dist < radius*radius)
|
||||||
|
{
|
||||||
|
vector = vector / sqrtf(pow_dist);
|
||||||
|
data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i]));
|
||||||
|
launcher.manager.sendEvent(id,EDamage(1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntitiesData data;
|
||||||
|
uint i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShootGrid* grid;
|
||||||
|
BVHTree* tree;
|
||||||
|
BVHTree* static_tree;
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
//grid = launcher.manager.getSystem!ShootGridManager().grid;
|
||||||
|
tree = launcher.manager.getSystem!BVHBuilder().tree;
|
||||||
|
static_tree = launcher.manager.getSystem!StaticBVHBuilder().tree;
|
||||||
|
//if(grid is null)return false;
|
||||||
|
if(tree is null || static_tree is null)return false;
|
||||||
|
else return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
// State state;
|
||||||
|
// state.data = data;
|
||||||
|
// EntityID id;
|
||||||
|
// foreach(i; 0..data.length)
|
||||||
|
// {
|
||||||
|
// state.i = i;
|
||||||
|
// float radius = data.scale[i].x;
|
||||||
|
// if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max))
|
||||||
|
// {
|
||||||
|
// state.test(id);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
State state;
|
||||||
|
state.data = data;
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
state.i = i;
|
||||||
|
//float radius = data.scale[i].x;
|
||||||
|
AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]);
|
||||||
|
tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
||||||
|
static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DamageSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
mixin ECS.ReadOnlyDependencies!(ShootGridDependency);
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
///variable named "length" contain entites count
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
CHitPoints[] hit_points;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleEvent(Entity* entity, EDamage event)
|
||||||
|
{
|
||||||
|
EntityMeta meta = entity.getMeta();
|
||||||
|
CHitPoints* hp = meta.getComponent!CHitPoints;
|
||||||
|
hp.value -= event.damage;
|
||||||
|
if(hp.value < 0)launcher.manager.removeEntity(entity.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Functions ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
struct BrickBreakerDemo
|
||||||
|
{
|
||||||
|
__gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks.";
|
||||||
|
|
||||||
|
//EntityTemplate* tmpl;
|
||||||
|
Texture texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
__gshared BrickBreakerDemo* demo;
|
||||||
|
|
||||||
|
void brickBreakerRegister()
|
||||||
|
{
|
||||||
|
demo = Mallocator.make!BrickBreakerDemo;
|
||||||
|
|
||||||
|
demo.texture.create();
|
||||||
|
demo.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
|
launcher.manager.beginRegister();
|
||||||
|
|
||||||
|
registerRenderingModule(launcher.manager);
|
||||||
|
registerCollisionModule(launcher.manager);
|
||||||
|
|
||||||
|
launcher.manager.registerComponent!CLocation;
|
||||||
|
launcher.manager.registerComponent!CRotation;
|
||||||
|
launcher.manager.registerComponent!CScale;
|
||||||
|
launcher.manager.registerComponent!CTexCoords;
|
||||||
|
launcher.manager.registerComponent!CTexCoordsIndex;
|
||||||
|
launcher.manager.registerComponent!CVelocity;
|
||||||
|
launcher.manager.registerComponent!CInput;
|
||||||
|
launcher.manager.registerComponent!CPaddle;
|
||||||
|
launcher.manager.registerComponent!CDamping;
|
||||||
|
launcher.manager.registerComponent!CVelocityFactor;
|
||||||
|
launcher.manager.registerComponent!CBall;
|
||||||
|
launcher.manager.registerComponent!CHitPoints;
|
||||||
|
|
||||||
|
launcher.manager.registerEvent!EDamage;
|
||||||
|
|
||||||
|
launcher.manager.registerSystem!MoveSystem(-100);
|
||||||
|
launcher.manager.registerSystem!EdgeCollisionSystem(-99);
|
||||||
|
launcher.manager.registerSystem!BallCollisionSystem(-79);
|
||||||
|
launcher.manager.registerSystem!InputMovementSystem(-120);
|
||||||
|
launcher.manager.registerSystem!DampingSystem(-120);
|
||||||
|
launcher.manager.registerSystem!DamageSystem(-120);
|
||||||
|
|
||||||
|
launcher.manager.endRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
void brickBreakerStart()
|
||||||
|
{
|
||||||
|
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
||||||
|
draw_system.default_data.color = 0x80808080;
|
||||||
|
draw_system.default_data.texture = demo.texture;
|
||||||
|
draw_system.default_data.size = vec2(16,16);
|
||||||
|
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
||||||
|
draw_system.default_data.material_id = 0;
|
||||||
|
|
||||||
|
EntityTemplate* brick_tmpl = launcher.manager.allocateTemplate(
|
||||||
|
[CLocation.component_id, CScale.component_id, CColor.component_id,
|
||||||
|
CTexCoordsIndex.component_id, CBVH.component_id, CHitPoints.component_id,
|
||||||
|
CAABB.component_id, CStatic.component_id].staticArray
|
||||||
|
);
|
||||||
|
brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,40,16,8)*px);
|
||||||
|
brick_tmpl.getComponent!CColor().value = 0x80206020;
|
||||||
|
brick_tmpl.getComponent!CScale().value = vec2(16,8);
|
||||||
|
brick_tmpl.getComponent!CHitPoints().value = 2;
|
||||||
|
//brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2());
|
||||||
|
|
||||||
|
EntityTemplate* big_brick_tmpl = launcher.manager.allocateTemplate(brick_tmpl);
|
||||||
|
big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px);
|
||||||
|
big_brick_tmpl.getComponent!CScale().value = vec2(16,16);
|
||||||
|
|
||||||
|
EntityTemplate* paddle_tmpl = launcher.manager.allocateTemplate(
|
||||||
|
[CLocation.component_id, CScale.component_id, CInput.component_id,
|
||||||
|
CTexCoordsIndex.component_id, CPaddle.component_id, CVelocity.component_id,
|
||||||
|
CDamping.component_id, CVelocityFactor.component_id, CBVH.component_id,
|
||||||
|
CAABB.component_id].staticArray
|
||||||
|
);
|
||||||
|
paddle_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(272,48,64,10)*px);
|
||||||
|
paddle_tmpl.getComponent!CScale().value = vec2(64,10);
|
||||||
|
paddle_tmpl.getComponent!CDamping().value = 14;
|
||||||
|
paddle_tmpl.getComponent!CVelocityFactor().value = vec2(1,0);
|
||||||
|
|
||||||
|
EntityTemplate* ball_tmpl = launcher.manager.allocateTemplate(
|
||||||
|
[CLocation.component_id, CScale.component_id, //CDamping.component_id,
|
||||||
|
CTexCoordsIndex.component_id, CBall.component_id, CVelocity.component_id].staticArray
|
||||||
|
);
|
||||||
|
ball_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,32,8,8)*px);
|
||||||
|
ball_tmpl.getComponent!CScale().value = vec2(8,8);
|
||||||
|
ball_tmpl.getComponent!CVelocity().value = vec2(0.1,0.1);
|
||||||
|
// paddle_tmpl.getComponent!CDamping().value = 14;
|
||||||
|
|
||||||
|
launcher.gui_manager.addComponent(CLocation(), "Location");
|
||||||
|
launcher.gui_manager.addComponent(CRotation(), "Rotation");
|
||||||
|
launcher.gui_manager.addComponent(CScale(), "Scale");
|
||||||
|
launcher.gui_manager.addComponent(CColor(), "Color");
|
||||||
|
launcher.gui_manager.addComponent(CTexCoords(), "Tex Coords");
|
||||||
|
launcher.gui_manager.addComponent(CTexCoordsIndex(), "Tex Coords Index");
|
||||||
|
launcher.gui_manager.addComponent(CVelocity(), "Velocity");
|
||||||
|
launcher.gui_manager.addComponent(CInput(), "Velocity");
|
||||||
|
launcher.gui_manager.addComponent(CDamping(), "Damping");
|
||||||
|
launcher.gui_manager.addComponent(CBall(), "Ball");
|
||||||
|
launcher.gui_manager.addComponent(CBVH(), "BVH");
|
||||||
|
launcher.gui_manager.addComponent(CAABB(), "AABB");
|
||||||
|
|
||||||
|
launcher.gui_manager.addSystem(MoveSystem.system_id, "Move System");
|
||||||
|
launcher.gui_manager.addSystem(EdgeCollisionSystem.system_id, "Edge Collision System");
|
||||||
|
launcher.gui_manager.addSystem(BallCollisionSystem.system_id, "Ball Collision System");
|
||||||
|
launcher.gui_manager.addSystem(InputMovementSystem.system_id, "Input Movement System");
|
||||||
|
launcher.gui_manager.addSystem(DampingSystem.system_id, "Damping System");
|
||||||
|
launcher.gui_manager.addSystem(DamageSystem.system_id, "Damage System");
|
||||||
|
|
||||||
|
launcher.gui_manager.addTemplate(brick_tmpl, "Brick");
|
||||||
|
launcher.gui_manager.addTemplate(big_brick_tmpl, "Big Brick");
|
||||||
|
launcher.gui_manager.addTemplate(paddle_tmpl, "Paddle");
|
||||||
|
launcher.gui_manager.addTemplate(ball_tmpl, "Ball");
|
||||||
|
|
||||||
|
foreach(i;0..10)
|
||||||
|
{
|
||||||
|
CColor color;
|
||||||
|
final switch(i)
|
||||||
|
{
|
||||||
|
case 0:color = 0x80206020;break;
|
||||||
|
case 1:color = 0x80602020;break;
|
||||||
|
case 2:color = 0x80202060;break;
|
||||||
|
case 3:color = 0x80206060;break;
|
||||||
|
case 4:color = 0x80606020;break;
|
||||||
|
case 5:color = 0x80602060;break;
|
||||||
|
case 6:color = 0x80606060;break;
|
||||||
|
case 7:color = 0x80202020;break;
|
||||||
|
case 8:color = 0x80008030;break;
|
||||||
|
case 9:color = 0x80206080;break;
|
||||||
|
}
|
||||||
|
foreach (j; 0..20)
|
||||||
|
{
|
||||||
|
launcher.manager.addEntity(brick_tmpl,[CLocation(vec2(j*18,300-i*10)).ref_, color.ref_].staticArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
launcher.manager.addEntity(paddle_tmpl,[CLocation(vec2(190,20)).ref_].staticArray);
|
||||||
|
launcher.manager.addEntity(ball_tmpl,[CLocation(vec2(190,40)).ref_].staticArray);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void brickBreakerEnd()
|
||||||
|
{
|
||||||
|
demo.texture.destroy();
|
||||||
|
|
||||||
|
Mallocator.dispose(demo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void brickBreakerEvent(SDL_Event* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool brickBreakerLoop()
|
||||||
|
{
|
||||||
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
|
launcher.manager.begin();
|
||||||
|
if(launcher.multithreading)
|
||||||
|
{
|
||||||
|
launcher.job_updater.begin();
|
||||||
|
launcher.manager.updateMT();
|
||||||
|
launcher.job_updater.call();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
launcher.manager.update();
|
||||||
|
}
|
||||||
|
launcher.manager.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCallbacks getBrickBreakerDemo()
|
||||||
|
{
|
||||||
|
DemoCallbacks demo;
|
||||||
|
demo.register = &brickBreakerRegister;
|
||||||
|
demo.initialize = &brickBreakerStart;
|
||||||
|
demo.deinitialize = &brickBreakerEnd;
|
||||||
|
demo.loop = &brickBreakerLoop;
|
||||||
|
demo.tips = .demo.tips;
|
||||||
|
return demo;
|
||||||
|
}
|
||||||
591
demos/source/demos/particles.d
Normal file
591
demos/source/demos/particles.d
Normal file
|
|
@ -0,0 +1,591 @@
|
||||||
|
module demos.particles;
|
||||||
|
|
||||||
|
import app;
|
||||||
|
|
||||||
|
import bindbc.sdl;
|
||||||
|
|
||||||
|
import cimgui.cimgui;
|
||||||
|
|
||||||
|
import bubel.ecs.attributes;
|
||||||
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.entity;
|
||||||
|
import bubel.ecs.manager;
|
||||||
|
import bubel.ecs.std;
|
||||||
|
|
||||||
|
import ecs_utils.gfx.texture;
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
import ecs_utils.utils;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
|
import game_core.rendering;
|
||||||
|
|
||||||
|
import gui.attributes;
|
||||||
|
|
||||||
|
extern(C):
|
||||||
|
|
||||||
|
private enum float px = 1.0/512.0;
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Components ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
/*struct CLocation
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias location this;
|
||||||
|
|
||||||
|
vec2 location;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CColor
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
@GUIColor uint value = uint.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CTexCoords
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
vec4 value;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// struct CVelocity
|
||||||
|
// {
|
||||||
|
// mixin ECS.Component;
|
||||||
|
|
||||||
|
// alias value this;
|
||||||
|
|
||||||
|
// vec2 value = vec2(0);
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct CForceRange
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
vec2 range = vec2(20,200);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CAttractor
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
//alias value this;
|
||||||
|
float strength = 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CVortex
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
float strength = 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct CDamping
|
||||||
|
// {
|
||||||
|
// mixin ECS.Component;
|
||||||
|
|
||||||
|
// alias power this;
|
||||||
|
|
||||||
|
// @GUIRange(0,9) ubyte power = 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct CGravity
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CParticleLife
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
this(float life_in_secs)
|
||||||
|
{
|
||||||
|
life = cast(int)(life_in_secs * 1000_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
alias life this;
|
||||||
|
|
||||||
|
int life = 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
/*
|
||||||
|
struct DrawSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
//uint thread_id;
|
||||||
|
uint job_id;
|
||||||
|
//@readonly CTexCoords[] coords;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
|
||||||
|
@optional @readonly CColor[] color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(2,2);
|
||||||
|
draw_data.coords = vec4(246,64,2,2)*px;
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.material_id = 2;
|
||||||
|
draw_data.thread_id = data.job_id;
|
||||||
|
draw_data.texture = particles_demo.texture;
|
||||||
|
|
||||||
|
if(!data.color)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, 0x80808080, 0, 2, 0, data.job_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i].value;
|
||||||
|
launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, data.color[i].value, 0, 2, 0, data.job_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// struct MoveSystem
|
||||||
|
// {
|
||||||
|
// mixin ECS.System!64;
|
||||||
|
|
||||||
|
// struct EntitiesData
|
||||||
|
// {
|
||||||
|
// uint length;
|
||||||
|
// CLocation[] locations;
|
||||||
|
// @readonly CVelocity[] velocity;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void onUpdate(EntitiesData data)
|
||||||
|
// {
|
||||||
|
// foreach(i; 0..data.length)
|
||||||
|
// {
|
||||||
|
// data.locations[i] += data.velocity[i] * launcher.delta_time;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct MouseAttractSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mouse_pos;
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
if(!launcher.getKeyState(SDL_SCANCODE_SPACE))return false;
|
||||||
|
mouse_pos = launcher.mouse.position;
|
||||||
|
mouse_pos = vec2(mouse_pos.x, mouse_pos.y) * launcher.scalling - launcher.render_position;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
float speed = launcher.delta_time * 0.01;
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
vec2 rel_pos = mouse_pos - data.locations[i];
|
||||||
|
float len2 = rel_pos.x * rel_pos.x + rel_pos.y * rel_pos.y;
|
||||||
|
if(len2 < 0.1)len2 = 0.1;
|
||||||
|
data.velocity[i] = data.velocity[i] + rel_pos / len2 * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AttractSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Updater
|
||||||
|
{
|
||||||
|
AttractSystem.EntitiesData data;
|
||||||
|
|
||||||
|
void onUpdate(AttractorIterator.EntitiesData adata)
|
||||||
|
{
|
||||||
|
float speed = launcher.delta_time * 0.00004;
|
||||||
|
if(adata.vortex)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
foreach(j;0..adata.length)
|
||||||
|
{
|
||||||
|
vec2 rel_pos = data.locations[i] - adata.locations[j];
|
||||||
|
float len2 = rel_pos.length2();
|
||||||
|
float inv_len = rsqrt(len2);
|
||||||
|
|
||||||
|
if(1 < adata.force_range[j].range.y*inv_len)
|
||||||
|
{
|
||||||
|
float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1;
|
||||||
|
|
||||||
|
vec2 vec = rel_pos * inv_len;
|
||||||
|
vec2 cvec = vec2(-vec.y,vec.x);
|
||||||
|
|
||||||
|
float sign = -1;
|
||||||
|
if(1 < adata.force_range[j].range.x*inv_len)sign = 1;
|
||||||
|
|
||||||
|
float str = adata.attractor[j].strength * sign;
|
||||||
|
float vortex_str = adata.vortex[j].strength;
|
||||||
|
data.velocity[i] = data.velocity[i] + (rel_pos * str + cvec * vortex_str) * speed * dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
foreach(j;0..adata.length)
|
||||||
|
{
|
||||||
|
vec2 rel_pos = data.locations[i] - adata.locations[j];
|
||||||
|
float len2 = rel_pos.length2();
|
||||||
|
float inv_len = rsqrt(len2);
|
||||||
|
|
||||||
|
if(1 < adata.force_range[j].range.y*inv_len)
|
||||||
|
{
|
||||||
|
float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1;
|
||||||
|
|
||||||
|
vec2 vec = rel_pos;
|
||||||
|
|
||||||
|
float sign = -1;
|
||||||
|
if(1 < adata.force_range[j].range.x*inv_len)sign = 1;
|
||||||
|
|
||||||
|
float str = adata.attractor[j].strength * speed * dist * sign;
|
||||||
|
data.velocity[i] = data.velocity[i] + vec * str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
Updater updater;
|
||||||
|
updater.data = data;
|
||||||
|
launcher.manager.callEntitiesFunction!AttractorIterator(&updater.onUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AttractorIterator
|
||||||
|
{
|
||||||
|
mixin ECS.System!1;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
@readonly CAttractor[] attractor;
|
||||||
|
@readonly CForceRange[] force_range;
|
||||||
|
@optional @readonly CVortex[] vortex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PlayAreaSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
Entity[] entity;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
if(data.locations[i].x > 440)launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
else if(data.locations[i].x < -40)launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
if(data.locations[i].y > 340)launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
else if(data.locations[i].y < -40)launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// struct DampingSystem
|
||||||
|
// {
|
||||||
|
// mixin ECS.System!32;
|
||||||
|
|
||||||
|
// struct EntitiesData
|
||||||
|
// {
|
||||||
|
// uint length;
|
||||||
|
// const (Entity)[] entity;
|
||||||
|
// @readonly CDamping[] damping;
|
||||||
|
// CVelocity[] velocity;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float[10] damp = 0;
|
||||||
|
|
||||||
|
// bool onBegin()
|
||||||
|
// {
|
||||||
|
// foreach(i;0..10)
|
||||||
|
// {
|
||||||
|
// damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void onUpdate(EntitiesData data)
|
||||||
|
// {
|
||||||
|
// foreach(i; 0..data.length)
|
||||||
|
// {
|
||||||
|
// data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct ParticleLifeSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
CParticleLife[] life;
|
||||||
|
}
|
||||||
|
|
||||||
|
int delta_time;
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
delta_time = cast(int)(launcher.delta_time * 1000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.life[i] -= delta_time;
|
||||||
|
if(data.life[i] < 0)launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GravitySystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
@readonly CGravity[] gravity;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
float delta_time = launcher.delta_time * 0.00_092;
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.velocity[i].y -= delta_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Functions ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
struct ParticlesDemo
|
||||||
|
{
|
||||||
|
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window.";
|
||||||
|
|
||||||
|
Texture texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
__gshared ParticlesDemo* particles_demo;
|
||||||
|
|
||||||
|
void particlesRegister()
|
||||||
|
{
|
||||||
|
particles_demo = Mallocator.make!ParticlesDemo;
|
||||||
|
|
||||||
|
particles_demo.texture.create();
|
||||||
|
particles_demo.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
|
launcher.manager.beginRegister();
|
||||||
|
|
||||||
|
registerRenderingModule(launcher.manager);
|
||||||
|
|
||||||
|
launcher.manager.registerComponent!CLocation;
|
||||||
|
//launcher.manager.registerComponent!CTexCoords;
|
||||||
|
launcher.manager.registerComponent!CColor;
|
||||||
|
launcher.manager.registerComponent!CVelocity;
|
||||||
|
launcher.manager.registerComponent!CScale;
|
||||||
|
launcher.manager.registerComponent!CTexCoords;
|
||||||
|
launcher.manager.registerComponent!CTexCoordsIndex;
|
||||||
|
launcher.manager.registerComponent!CRotation;
|
||||||
|
launcher.manager.registerComponent!CDepth;
|
||||||
|
launcher.manager.registerComponent!CAttractor;
|
||||||
|
launcher.manager.registerComponent!CDamping;
|
||||||
|
launcher.manager.registerComponent!CGravity;
|
||||||
|
launcher.manager.registerComponent!CVortex;
|
||||||
|
launcher.manager.registerComponent!CParticleLife;
|
||||||
|
launcher.manager.registerComponent!CForceRange;
|
||||||
|
launcher.manager.registerComponent!CMaterialIndex;
|
||||||
|
|
||||||
|
launcher.manager.registerSystem!MoveSystem(0);
|
||||||
|
launcher.manager.registerSystem!DrawSystem(100);
|
||||||
|
launcher.manager.registerSystem!PlayAreaSystem(102);
|
||||||
|
launcher.manager.registerSystem!AttractSystem(-1);
|
||||||
|
launcher.manager.registerSystem!MouseAttractSystem(1);
|
||||||
|
launcher.manager.registerSystem!DampingSystem(101);
|
||||||
|
launcher.manager.registerSystem!ParticleLifeSystem(-10);
|
||||||
|
launcher.manager.registerSystem!GravitySystem(-2);
|
||||||
|
|
||||||
|
launcher.manager.registerSystem!AttractorIterator(-1);
|
||||||
|
|
||||||
|
launcher.manager.endRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
void particlesStart()
|
||||||
|
{
|
||||||
|
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
||||||
|
draw_system.default_data.size = vec2(2,2);
|
||||||
|
draw_system.default_data.coords = vec4(246,64,2,2)*px;
|
||||||
|
draw_system.default_data.material_id = 2;
|
||||||
|
draw_system.default_data.texture = particles_demo.texture;
|
||||||
|
|
||||||
|
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System");
|
||||||
|
launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System");
|
||||||
|
launcher.gui_manager.addSystem(PlayAreaSystem.system_id,"Play Area System");
|
||||||
|
launcher.gui_manager.addSystem(AttractSystem.system_id,"Attract System");
|
||||||
|
launcher.gui_manager.addSystem(MouseAttractSystem.system_id,"Mouse Attract System");
|
||||||
|
launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System");
|
||||||
|
launcher.gui_manager.addSystem(ParticleLifeSystem.system_id,"Particle Life System");
|
||||||
|
|
||||||
|
// launcher.gui_manager.addComponent(CColor(),"Color (white)");
|
||||||
|
// launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)");
|
||||||
|
// launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)");
|
||||||
|
// launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)");
|
||||||
|
launcher.gui_manager.addComponent(CColor(0xFF101540),"Color");
|
||||||
|
launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor");
|
||||||
|
launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange");
|
||||||
|
launcher.gui_manager.addComponent(CVelocity(),"Velocity");
|
||||||
|
launcher.gui_manager.addComponent(CDamping(),"Damping");
|
||||||
|
launcher.gui_manager.addComponent(CVortex(),"Vortex");
|
||||||
|
launcher.gui_manager.addComponent(CParticleLife(),"Particle Life");
|
||||||
|
launcher.gui_manager.addComponent(CGravity(),"Gravity");
|
||||||
|
|
||||||
|
EntityTemplate* tmpl;
|
||||||
|
EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CTexCoords.component_id, CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id, CScale.component_id, CMaterialIndex.component_id].staticArray);
|
||||||
|
base_tmpl.getComponent!CColor().value = 0xFF251010;
|
||||||
|
base_tmpl.getComponent!CScale().value = vec2(2);
|
||||||
|
base_tmpl.getComponent!CTexCoords().value = vec4(246,64,2,2)*px;
|
||||||
|
base_tmpl.getComponent!CMaterialIndex().value = 2;
|
||||||
|
launcher.gui_manager.addTemplate(base_tmpl,"Particle");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
||||||
|
// tmpl.getComponent!CColor().value = 0xFF251010;
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (blue)");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
||||||
|
// tmpl.getComponent!CColor().value = 0xFF102010;
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (green)");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(base_tmpl);
|
||||||
|
// tmpl.getComponent!CColor().value = 0xFF101540;
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (red)");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(tmpl, [CDamping.component_id].staticArray);
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping)");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(tmpl);
|
||||||
|
// tmpl.getComponent!CDamping().power = 4;
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)");
|
||||||
|
tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id, CScale.component_id].staticArray);
|
||||||
|
tmpl.getComponent!CScale().value = vec2(4);
|
||||||
|
launcher.gui_manager.addTemplate(tmpl,"Attractor");
|
||||||
|
tmpl = launcher.manager.allocateTemplate(tmpl, [CVortex.component_id].staticArray);
|
||||||
|
launcher.gui_manager.addTemplate(tmpl,"Vortex");
|
||||||
|
// tmpl = launcher.manager.allocateTemplate(tmpl);
|
||||||
|
// tmpl.getComponent!CVortex().strength = -0.6;
|
||||||
|
// launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void particlesEnd()
|
||||||
|
{
|
||||||
|
particles_demo.texture.destroy();
|
||||||
|
|
||||||
|
//launcher.manager.freeTemplate(simple.tmpl);
|
||||||
|
Mallocator.dispose(particles_demo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void particlesEvent(SDL_Event* event)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool particlesLoop()
|
||||||
|
{
|
||||||
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
|
launcher.manager.begin();
|
||||||
|
if(launcher.multithreading)
|
||||||
|
{
|
||||||
|
launcher.job_updater.begin();
|
||||||
|
launcher.manager.updateMT();
|
||||||
|
launcher.job_updater.call();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
launcher.manager.update();
|
||||||
|
}
|
||||||
|
launcher.manager.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCallbacks getParticlesDemo()
|
||||||
|
{
|
||||||
|
DemoCallbacks demo;
|
||||||
|
demo.register = &particlesRegister;
|
||||||
|
demo.initialize = &particlesStart;
|
||||||
|
demo.deinitialize = &particlesEnd;
|
||||||
|
demo.loop = &particlesLoop;
|
||||||
|
demo.tips = ParticlesDemo.tips;
|
||||||
|
return demo;
|
||||||
|
}
|
||||||
101
demos/source/demos/sandbox.d
Normal file
101
demos/source/demos/sandbox.d
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
module demos.sandbox;
|
||||||
|
|
||||||
|
import bindbc.sdl;
|
||||||
|
|
||||||
|
import demos.simple;
|
||||||
|
import demos.snake;
|
||||||
|
import demos.space_invaders;
|
||||||
|
import demos.particles;
|
||||||
|
import demos.brick_breaker;
|
||||||
|
|
||||||
|
import game_core.rendering;
|
||||||
|
|
||||||
|
import app;
|
||||||
|
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
extern(C):
|
||||||
|
|
||||||
|
void sandboxStart()
|
||||||
|
{
|
||||||
|
simpleRegister();
|
||||||
|
snakeRegister();
|
||||||
|
spaceInvadersRegister();
|
||||||
|
particlesRegister();
|
||||||
|
brickBreakerRegister();
|
||||||
|
|
||||||
|
simpleStart();
|
||||||
|
snakeStart();
|
||||||
|
spaceInvadersStart();
|
||||||
|
particlesStart();
|
||||||
|
brickBreakerStart();
|
||||||
|
|
||||||
|
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
||||||
|
draw_system.default_data.size = vec2(16,16);
|
||||||
|
draw_system.default_data.coords = vec4(0,48,16,16)*demos.simple.px;
|
||||||
|
draw_system.default_data.material_id = 0;
|
||||||
|
draw_system.default_data.texture = particles_demo.texture;
|
||||||
|
draw_system.default_data.color = 0x80808080;
|
||||||
|
|
||||||
|
launcher.manager.getSystem(MouseAttractSystem.system_id).disable();
|
||||||
|
launcher.manager.getSystem(demos.simple.MoveSystem.system_id).disable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void sandboxEnd()
|
||||||
|
{
|
||||||
|
simpleEnd();
|
||||||
|
snakeEnd();
|
||||||
|
spaceInvadersEnd();
|
||||||
|
particlesEnd();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void sandboxEvent(SDL_Event* event)
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
|
||||||
|
bool sandboxLoop()
|
||||||
|
{
|
||||||
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5;
|
||||||
|
|
||||||
|
launcher.manager.begin();
|
||||||
|
|
||||||
|
float delta_time = launcher.delta_time;
|
||||||
|
if(delta_time > 2000)delta_time = 2000;
|
||||||
|
__gshared float time = 0;
|
||||||
|
|
||||||
|
/*if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3;
|
||||||
|
else */
|
||||||
|
time += delta_time;
|
||||||
|
|
||||||
|
while(time > 200)
|
||||||
|
{
|
||||||
|
time -= 200;
|
||||||
|
|
||||||
|
launcher.manager.update("fixed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(launcher.multithreading)
|
||||||
|
{
|
||||||
|
launcher.job_updater.begin();
|
||||||
|
launcher.manager.updateMT();
|
||||||
|
launcher.job_updater.call();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
launcher.manager.update();
|
||||||
|
}
|
||||||
|
launcher.manager.end();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCallbacks getSanboxDemo()
|
||||||
|
{
|
||||||
|
DemoCallbacks demo;
|
||||||
|
demo.initialize = &sandboxStart;
|
||||||
|
demo.deinitialize = &sandboxEnd;
|
||||||
|
demo.loop = &sandboxLoop;
|
||||||
|
demo.tips = "tips";
|
||||||
|
return demo;
|
||||||
|
}
|
||||||
|
|
@ -4,47 +4,42 @@ import app;
|
||||||
|
|
||||||
import bindbc.sdl;
|
import bindbc.sdl;
|
||||||
|
|
||||||
import cimgui.cimgui;
|
|
||||||
|
|
||||||
import bubel.ecs.attributes;
|
import bubel.ecs.attributes;
|
||||||
import bubel.ecs.core;
|
import bubel.ecs.core;
|
||||||
import bubel.ecs.entity;
|
import bubel.ecs.entity;
|
||||||
import bubel.ecs.manager;
|
import bubel.ecs.manager;
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
|
|
||||||
|
import cimgui.cimgui;
|
||||||
|
|
||||||
import ecs_utils.gfx.texture;
|
import ecs_utils.gfx.texture;
|
||||||
import ecs_utils.math.vector;
|
import ecs_utils.math.vector;
|
||||||
import ecs_utils.utils;
|
import ecs_utils.utils;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
|
import game_core.rendering;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
struct Simple
|
enum float px = 1.0/512.0;
|
||||||
{
|
|
||||||
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window.";
|
|
||||||
|
|
||||||
EntityTemplate* tmpl;
|
/*#######################################################################################################################
|
||||||
Texture texture;
|
------------------------------------------------ Components ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
bool move_system = true;
|
/*struct CLocation
|
||||||
bool draw_system = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CLocation
|
|
||||||
{
|
{
|
||||||
mixin ECS.Component;
|
mixin ECS.Component;
|
||||||
|
|
||||||
alias location this;
|
alias location this;
|
||||||
|
|
||||||
vec2 location;
|
vec2 location;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
struct CTexture
|
|
||||||
{
|
|
||||||
mixin ECS.Component;
|
|
||||||
|
|
||||||
Texture tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
/*
|
||||||
struct DrawSystem
|
struct DrawSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!32;
|
mixin ECS.System!32;
|
||||||
|
|
@ -54,22 +49,29 @@ struct DrawSystem
|
||||||
uint length;
|
uint length;
|
||||||
//uint thread_id;
|
//uint thread_id;
|
||||||
uint job_id;
|
uint job_id;
|
||||||
@readonly CTexture[] textures;
|
|
||||||
@readonly CLocation[] locations;
|
@readonly CLocation[] locations;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
|
if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(16,16);
|
||||||
|
draw_data.coords = vec4(0,0,1,1);
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.material_id = 0;
|
||||||
|
draw_data.thread_id = data.job_id;
|
||||||
|
draw_data.texture = simple.texture;
|
||||||
|
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id);
|
draw_data.position = data.locations[i];
|
||||||
// launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0x80808080, 0, 0, 0, data.job_id);
|
draw_data.depth = cast(ushort)(data.locations[i].y);
|
||||||
//draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1));
|
launcher.renderer.draw(draw_data);
|
||||||
}
|
}
|
||||||
//if(data.thread_id == 0)launcher.renderer.pushData();
|
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
struct MoveSystem
|
struct MoveSystem
|
||||||
{
|
{
|
||||||
|
|
@ -85,47 +87,67 @@ struct MoveSystem
|
||||||
{
|
{
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
data.locations[i].location.y = data.locations[i].location.y + 1;
|
data.locations[i].y = data.locations[i].y + 1;
|
||||||
if(data.locations[i].location.y > 300)data.locations[i].location.y = 0;
|
if(data.locations[i].y > 300)data.locations[i].y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*#######################################################################################################################
|
||||||
|
------------------------------------------------ Functions ------------------------------------------------------------------
|
||||||
|
#######################################################################################################################*/
|
||||||
|
|
||||||
|
struct Simple
|
||||||
|
{
|
||||||
|
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window.";
|
||||||
|
|
||||||
|
EntityTemplate* tmpl;
|
||||||
|
Texture texture;
|
||||||
|
}
|
||||||
|
|
||||||
__gshared Simple* simple;
|
__gshared Simple* simple;
|
||||||
|
|
||||||
void simpleStart()
|
void simpleRegister()
|
||||||
{
|
{
|
||||||
simple = Mallocator.make!Simple;
|
simple = Mallocator.make!Simple;
|
||||||
|
|
||||||
simple.texture.create();
|
simple.texture.create();
|
||||||
simple.texture.load("assets/textures/buckler.png");
|
simple.texture.load("assets/textures/atlas.png");
|
||||||
|
|
||||||
launcher.manager.beginRegister();
|
launcher.manager.beginRegister();
|
||||||
|
|
||||||
|
registerRenderingModule(launcher.manager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
launcher.manager.registerComponent!CLocation;
|
||||||
launcher.manager.registerComponent!CTexture;
|
|
||||||
|
|
||||||
launcher.manager.registerSystem!MoveSystem(0);
|
launcher.manager.registerSystem!MoveSystem(0);
|
||||||
launcher.manager.registerSystem!DrawSystem(1);
|
// launcher.manager.registerSystem!DrawSystem(1);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
launcher.manager.endRegister();
|
||||||
|
}
|
||||||
|
|
||||||
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System");
|
void simpleStart()
|
||||||
|
{
|
||||||
|
DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem;
|
||||||
|
draw_system.default_data.color = 0x80808080;
|
||||||
|
draw_system.default_data.texture = simple.texture;
|
||||||
|
draw_system.default_data.size = vec2(16,16);
|
||||||
|
draw_system.default_data.coords = vec4(0,48,16,16)*px;//vec4(0,0,1,1);
|
||||||
|
|
||||||
|
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move Up System");
|
||||||
launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System");
|
launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System");
|
||||||
|
|
||||||
ushort[2] components = [CLocation.component_id, CTexture.component_id];
|
simple.tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CDrawDefault.component_id].staticArray);
|
||||||
simple.tmpl = launcher.manager.allocateTemplate(components);
|
//*simple.tmpl.getComponent!CTexCoordsIndex = TexCoordsManager.instance.getCoordIndex(vec4(0,48,16,16)*px);
|
||||||
CTexture* tex_comp = simple.tmpl.getComponent!CTexture;
|
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||||
tex_comp.tex = simple.texture;
|
|
||||||
CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
|
||||||
|
|
||||||
launcher.gui_manager.addTemplate(simple.tmpl, "Basic");
|
launcher.gui_manager.addTemplate(simple.tmpl, "Basic");
|
||||||
|
|
||||||
foreach(i; 0..10)
|
foreach(i; 0..10)
|
||||||
foreach(j; 0..10)
|
foreach(j; 0..10)
|
||||||
{
|
{
|
||||||
loc_comp.location = vec2(i*16+64,j*16+64);
|
//loc_comp.value = vec2(i*16+64,j*16+64);
|
||||||
launcher.manager.addEntity(simple.tmpl);
|
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,46 +162,15 @@ void simpleEnd()
|
||||||
Mallocator.dispose(simple);
|
Mallocator.dispose(simple);
|
||||||
}
|
}
|
||||||
|
|
||||||
void simpleTool(vec2 position, Tool tool, int size)
|
|
||||||
{
|
|
||||||
switch(tool)
|
|
||||||
{
|
|
||||||
case Tool.entity_spawner:
|
|
||||||
{
|
|
||||||
EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate();
|
|
||||||
CLocation* location = tmpl.getComponent!CLocation;
|
|
||||||
if(location)
|
|
||||||
{
|
|
||||||
position.x += (randomf - 0.5) * size;
|
|
||||||
position.y += (randomf - 0.5) * size;
|
|
||||||
if(position.x > 400)position.x -= 400;
|
|
||||||
else if(position.x < 0)position.x += 400;
|
|
||||||
if(position.y > 300)position.y -= 300;
|
|
||||||
else if(position.y < 0)position.y += 300;
|
|
||||||
*location = position;
|
|
||||||
}
|
|
||||||
launcher.manager.addEntity(tmpl);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void simpleEvent(SDL_Event* event)
|
void simpleEvent(SDL_Event* event)
|
||||||
{
|
{
|
||||||
/*if(event.type == event.button)
|
|
||||||
{
|
|
||||||
vec2 position = vec2(event.button.x, event.button.y);
|
|
||||||
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spawnEntity()
|
void spawnEntity()
|
||||||
{
|
{
|
||||||
CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||||
loc_comp.location = vec2(randomf() * 400,0);
|
//loc_comp.value = vec2(randomf() * 400,0);
|
||||||
launcher.manager.addEntity(simple.tmpl);
|
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simpleLoop()
|
bool simpleLoop()
|
||||||
|
|
@ -188,7 +179,7 @@ bool simpleLoop()
|
||||||
|
|
||||||
if(launcher.getKeyState(SDL_SCANCODE_SPACE))
|
if(launcher.getKeyState(SDL_SCANCODE_SPACE))
|
||||||
{
|
{
|
||||||
foreach(i;0..1)spawnEntity();
|
foreach(i;0..20)spawnEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
launcher.manager.begin();
|
launcher.manager.begin();
|
||||||
|
|
@ -205,4 +196,15 @@ bool simpleLoop()
|
||||||
launcher.manager.end();
|
launcher.manager.end();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCallbacks getSimpleDemo()
|
||||||
|
{
|
||||||
|
DemoCallbacks demo;
|
||||||
|
demo.register = &simpleRegister;
|
||||||
|
demo.initialize = &simpleStart;
|
||||||
|
demo.deinitialize = &simpleEnd;
|
||||||
|
demo.loop = &simpleLoop;
|
||||||
|
demo.tips = simple.tips;
|
||||||
|
return demo;
|
||||||
}
|
}
|
||||||
|
|
@ -4,8 +4,6 @@ import app;
|
||||||
|
|
||||||
import bindbc.sdl;
|
import bindbc.sdl;
|
||||||
|
|
||||||
import cimgui.cimgui;
|
|
||||||
|
|
||||||
import bubel.ecs.attributes;
|
import bubel.ecs.attributes;
|
||||||
import bubel.ecs.core;
|
import bubel.ecs.core;
|
||||||
import bubel.ecs.entity;
|
import bubel.ecs.entity;
|
||||||
|
|
@ -13,10 +11,14 @@ import bubel.ecs.manager;
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
|
|
||||||
|
import cimgui.cimgui;
|
||||||
|
|
||||||
import ecs_utils.gfx.texture;
|
import ecs_utils.gfx.texture;
|
||||||
import ecs_utils.math.vector;
|
import ecs_utils.math.vector;
|
||||||
import ecs_utils.utils;
|
import ecs_utils.utils;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
|
|
||||||
//import std.array : staticArray;
|
//import std.array : staticArray;
|
||||||
|
|
||||||
enum float px = 1.0/512.0;
|
enum float px = 1.0/512.0;
|
||||||
|
|
@ -31,22 +33,6 @@ struct MapElement
|
||||||
apple = 1,
|
apple = 1,
|
||||||
wall = 2,
|
wall = 2,
|
||||||
snake = 3,
|
snake = 3,
|
||||||
|
|
||||||
/* snake_head_up = 5,
|
|
||||||
snake_head_down = 6,
|
|
||||||
snake_head_left = 7,
|
|
||||||
snake_head_right = 8,
|
|
||||||
snake_tail_up = 9,
|
|
||||||
snake_tail_down = 10,
|
|
||||||
snake_tail_left = 11,
|
|
||||||
snake_tail_right = 12,
|
|
||||||
snake_turn_ld = 13,
|
|
||||||
snake_turn_lu = 14,
|
|
||||||
snake_turn_rd = 15,
|
|
||||||
snake_turn_ru = 16,
|
|
||||||
snake_vertical = 17,
|
|
||||||
snake_horizontal = 18*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Type type;
|
Type type;
|
||||||
EntityID id;
|
EntityID id;
|
||||||
|
|
@ -86,7 +72,7 @@ struct Snake
|
||||||
bool move_system = true;
|
bool move_system = true;
|
||||||
bool draw_system = true;
|
bool draw_system = true;
|
||||||
|
|
||||||
const int map_size = 18;
|
enum int map_size = 18;
|
||||||
|
|
||||||
MapElement[map_size * map_size] map;
|
MapElement[map_size * map_size] map;
|
||||||
|
|
||||||
|
|
@ -97,7 +83,7 @@ struct Snake
|
||||||
if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl);
|
if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl);
|
||||||
if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl);
|
if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl);
|
||||||
if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle);
|
if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle);
|
||||||
texture.destory();
|
texture.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
MapElement element(ivec2 pos)
|
MapElement element(ivec2 pos)
|
||||||
|
|
@ -129,10 +115,7 @@ struct Snake
|
||||||
}
|
}
|
||||||
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
|
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
|
||||||
}
|
}
|
||||||
//CILocation* location = apple_tmpl.getComponent!CILocation;
|
launcher.manager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray);
|
||||||
//*location = random_pos;
|
|
||||||
//Entity* apple =
|
|
||||||
launcher.manager.addEntity(apple_tmpl,[CILocation(random_pos).ref_].staticArray);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,14 +141,14 @@ struct CILocation
|
||||||
ivec2 location;
|
ivec2 location;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CLocation
|
// struct CLocation
|
||||||
{
|
// {
|
||||||
mixin ECS.Component;
|
// mixin ECS.Component;
|
||||||
|
|
||||||
alias location this;
|
// alias location this;
|
||||||
|
|
||||||
vec2 location = vec2(0,0);
|
// vec2 location = vec2(0,0);
|
||||||
}
|
// }
|
||||||
|
|
||||||
struct CSnake
|
struct CSnake
|
||||||
{
|
{
|
||||||
|
|
@ -252,10 +235,10 @@ struct CMovement
|
||||||
Direction direction;
|
Direction direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CInput
|
// struct CInput
|
||||||
{
|
// {
|
||||||
mixin ECS.Component;
|
// mixin ECS.Component;
|
||||||
}
|
// }
|
||||||
|
|
||||||
struct AppleSystem
|
struct AppleSystem
|
||||||
{
|
{
|
||||||
|
|
@ -264,8 +247,8 @@ struct AppleSystem
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
uint length;
|
uint length;
|
||||||
@readonly Entity[] entities;
|
@readonly Entity[] entity;
|
||||||
@readonly CApple[] movement;
|
@readonly CApple[] apple;
|
||||||
@readonly CILocation[] location;
|
@readonly CILocation[] location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,7 +256,17 @@ struct AppleSystem
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
snake.element(MapElement(MapElement.Type.apple,data.entities[i].id),data.location[i]);
|
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]);
|
||||||
|
else launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRemoveEntity(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
if(snake.element(data.location[i].location).id == data.entity[i].id)
|
||||||
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +308,7 @@ struct ParticleMovementSystem
|
||||||
{
|
{
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
data.location[i].location -= data.movement[i].velocity;
|
data.location[i] -= data.movement[i].velocity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -355,9 +348,21 @@ struct AnimationRenderSystem
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(16,16);
|
||||||
|
//draw_data.coords = vec4(0,0,1,1)*px;
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.material_id = 0;
|
||||||
|
draw_data.thread_id = 0;
|
||||||
|
draw_data.texture = snake.texture;
|
||||||
|
draw_data.depth = -1;
|
||||||
foreach(i;0..data.length)
|
foreach(i;0..data.length)
|
||||||
{
|
{
|
||||||
launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080);
|
draw_data.position = data.location[i];
|
||||||
|
draw_data.coords = data.animation[i].frames[cast(int)(data.animation[i].time)];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
//launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -477,7 +482,12 @@ struct MoveSystem
|
||||||
break;
|
break;
|
||||||
case MapElement.Type.apple:
|
case MapElement.Type.apple:
|
||||||
launcher.manager.removeEntity(snake.element(data.location[i].location).id);
|
launcher.manager.removeEntity(snake.element(data.location[i].location).id);
|
||||||
if(data.snakes[i].parts.length < 100)data.snakes[i].parts.add(new_location);
|
if(data.snakes[i].parts.length >= 99)
|
||||||
|
{
|
||||||
|
snake.addApple();
|
||||||
|
goto case(MapElement.Type.empty);
|
||||||
|
}
|
||||||
|
data.snakes[i].parts.add(new_location);
|
||||||
|
|
||||||
if(data.snakes[i].parts.length > 1)
|
if(data.snakes[i].parts.length > 1)
|
||||||
{
|
{
|
||||||
|
|
@ -506,7 +516,40 @@ struct MoveSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SnakeSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!1;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
Entity[] entity;
|
||||||
|
@readonly CSnake[] snake;
|
||||||
|
@readonly CILocation[] location;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onAddSystem(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]);
|
||||||
|
else launcher.manager.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRemoveEntity(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
if(snake.element(data.location[i].location).id == data.entity[i].id)
|
||||||
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location);
|
||||||
|
foreach(part; data.snake[i].parts.array)
|
||||||
|
if(snake.element(part).id == data.entity[i].id)
|
||||||
|
snake.element(MapElement(MapElement.Type.empty, EntityID()),part);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -618,9 +661,19 @@ struct DrawAppleSystem
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(16,16);
|
||||||
|
draw_data.coords = vec4(0,32*px,16*px,16*px);
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.material_id = 0;
|
||||||
|
draw_data.thread_id = 0;
|
||||||
|
draw_data.texture = snake.texture;
|
||||||
foreach(i; 0..data.location.length)
|
foreach(i; 0..data.location.length)
|
||||||
{
|
{
|
||||||
launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0);
|
draw_data.position = vec2(data.location[i].x*16,data.location[i].y*16);
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
//launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -688,34 +741,49 @@ struct DrawSnakeSystem
|
||||||
|
|
||||||
static void drawElement(ivec2 loc, SnakePart part)
|
static void drawElement(ivec2 loc, SnakePart part)
|
||||||
{
|
{
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(16,16);
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.texture = snake.texture;
|
||||||
|
draw_data.position = cast(vec2)loc;
|
||||||
final switch(cast(ubyte)part)
|
final switch(cast(ubyte)part)
|
||||||
{
|
{
|
||||||
case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.tail_up:draw_data.coords = vec4(16,112,16,16)*px;break;
|
||||||
case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.tail_down:draw_data.coords = vec4(0,112,16,16)*px;break;
|
||||||
case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.tail_left:draw_data.coords = vec4(32,112,16,16)*px;break;
|
||||||
case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.tail_right:draw_data.coords = vec4(0,144,16,16)*px;break;
|
||||||
case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.turn_ld:draw_data.coords = vec4(64,128,16,16)*px;break;
|
||||||
case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.turn_lu:draw_data.coords = vec4(32,144,16,16)*px;break;
|
||||||
case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.turn_rd:draw_data.coords = vec4(16,144,16,16)*px;break;
|
||||||
case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.turn_ru:draw_data.coords = vec4(64,112,16,16)*px;break;
|
||||||
case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.vertical:draw_data.coords = vec4(16,128,16,16)*px;break;
|
||||||
case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, 0x80808080, 0);break;
|
case SnakePart.horizontal:draw_data.coords = vec4(48,128,16,16)*px;break;
|
||||||
}
|
}
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
{
|
{
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
Renderer.DrawData draw_data;
|
||||||
|
draw_data.size = vec2(16,16);
|
||||||
|
draw_data.color = 0x80808080;
|
||||||
|
draw_data.texture = snake.texture;
|
||||||
|
|
||||||
foreach(i; 0..data.length)
|
foreach(i; 0..data.length)
|
||||||
{
|
{
|
||||||
const (CSnake)* snake = &data.snake[i];
|
const (CSnake)* snake = &data.snake[i];
|
||||||
scope vec2 loc = cast(vec2)(data.location[i].location * 16);
|
scope vec2 loc = cast(vec2)(data.location[i].location * 16);
|
||||||
|
draw_data.position = loc;
|
||||||
final switch(snake.direction)
|
final switch(snake.direction)
|
||||||
{
|
{
|
||||||
case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, 0x80808080, 0);break;
|
case CMovement.Direction.up:draw_data.coords = vec4(48,112,16,16)*px;break;
|
||||||
case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, 0x80808080, 0);break;
|
case CMovement.Direction.down:draw_data.coords = vec4(48,144,16,16)*px;break;
|
||||||
case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, 0x80808080, 0);break;
|
case CMovement.Direction.left:draw_data.coords = vec4(0,128,16,16)*px;break;
|
||||||
case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, 0x80808080, 0);break;
|
case CMovement.Direction.right:draw_data.coords = vec4(32,128,16,16)*px;break;
|
||||||
}
|
}
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
if(snake.parts.length >1)
|
if(snake.parts.length >1)
|
||||||
{
|
{
|
||||||
foreach(j;1..snake.parts.length - 1)drawElement(snake.parts[j]*16, snakePart(snake.parts[j], snake.parts[j+1], snake.parts[j-1]));
|
foreach(j;1..snake.parts.length - 1)drawElement(snake.parts[j]*16, snakePart(snake.parts[j], snake.parts[j+1], snake.parts[j-1]));
|
||||||
|
|
@ -750,10 +818,41 @@ struct CleanSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CopyLocationSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
CLocation[] location;
|
||||||
|
@readonly CILocation[] ilocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onAddEntity(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
data.ilocation[i] = cast(ivec2)(data.location[i] / 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
data.location[i] = cast(vec2)(data.ilocation[i] * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__gshared Snake* snake;
|
__gshared Snake* snake;
|
||||||
|
|
||||||
void snakeStart()
|
void snakeRegister()
|
||||||
{
|
{
|
||||||
|
import game_core.rendering;
|
||||||
|
|
||||||
snake = Mallocator.make!Snake;
|
snake = Mallocator.make!Snake;
|
||||||
|
|
||||||
snake.texture.create();
|
snake.texture.create();
|
||||||
|
|
@ -763,6 +862,8 @@ void snakeStart()
|
||||||
|
|
||||||
launcher.manager.registerPass("fixed");
|
launcher.manager.registerPass("fixed");
|
||||||
|
|
||||||
|
registerRenderingModule(launcher.manager);
|
||||||
|
|
||||||
launcher.manager.registerComponent!CLocation;
|
launcher.manager.registerComponent!CLocation;
|
||||||
launcher.manager.registerComponent!CILocation;
|
launcher.manager.registerComponent!CILocation;
|
||||||
launcher.manager.registerComponent!CSnake;
|
launcher.manager.registerComponent!CSnake;
|
||||||
|
|
@ -776,7 +877,6 @@ void snakeStart()
|
||||||
launcher.manager.registerSystem!MoveSystem(0,"fixed");
|
launcher.manager.registerSystem!MoveSystem(0,"fixed");
|
||||||
launcher.manager.registerSystem!InputSystem(-100);
|
launcher.manager.registerSystem!InputSystem(-100);
|
||||||
launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
|
launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
|
||||||
launcher.manager.registerSystem!AppleSystem(-1,"fixed");
|
|
||||||
launcher.manager.registerSystem!AnimationRenderSystem(100);
|
launcher.manager.registerSystem!AnimationRenderSystem(100);
|
||||||
launcher.manager.registerSystem!AnimationSystem(-1);
|
launcher.manager.registerSystem!AnimationSystem(-1);
|
||||||
launcher.manager.registerSystem!ParticleSystem(-1);
|
launcher.manager.registerSystem!ParticleSystem(-1);
|
||||||
|
|
@ -784,7 +884,24 @@ void snakeStart()
|
||||||
launcher.manager.registerSystem!DrawAppleSystem(99);
|
launcher.manager.registerSystem!DrawAppleSystem(99);
|
||||||
launcher.manager.registerSystem!DrawSnakeSystem(101);
|
launcher.manager.registerSystem!DrawSnakeSystem(101);
|
||||||
|
|
||||||
|
launcher.manager.registerSystem!CopyLocationSystem(100);
|
||||||
|
//launcher.manager.registerSystem!AppleRemoveSystem(100);
|
||||||
|
launcher.manager.registerSystem!AppleSystem(101);
|
||||||
|
launcher.manager.registerSystem!SnakeSystem(101);
|
||||||
|
|
||||||
launcher.manager.endRegister();
|
launcher.manager.endRegister();
|
||||||
|
}
|
||||||
|
|
||||||
|
void snakeStart()
|
||||||
|
{
|
||||||
|
launcher.gui_manager.addComponent(CApple(),"Apple");
|
||||||
|
launcher.gui_manager.addComponent(CSnake(),"Snake");
|
||||||
|
launcher.gui_manager.addComponent(CParticle(1000),"Particle");
|
||||||
|
launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector");
|
||||||
|
launcher.gui_manager.addComponent(CInput(),"Input");
|
||||||
|
launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement");
|
||||||
|
//launcher.gui_manager.addComponent(CAnimation(),"Movement");
|
||||||
|
launcher.gui_manager.addComponent(CILocation(),"Int Location");
|
||||||
|
|
||||||
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System");
|
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System");
|
||||||
launcher.gui_manager.addSystem(InputSystem.system_id,"Input System");
|
launcher.gui_manager.addSystem(InputSystem.system_id,"Input System");
|
||||||
|
|
@ -793,19 +910,19 @@ void snakeStart()
|
||||||
launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System");
|
launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System");
|
||||||
launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle Life System");
|
launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle Life System");
|
||||||
launcher.gui_manager.addSystem(ParticleMovementSystem.system_id,"Particle Movement System");
|
launcher.gui_manager.addSystem(ParticleMovementSystem.system_id,"Particle Movement System");
|
||||||
|
launcher.gui_manager.addSystem(DrawAppleSystem.system_id,"Draw Apple System");
|
||||||
|
launcher.gui_manager.addSystem(DrawSnakeSystem.system_id,"Draw Snake System");
|
||||||
|
|
||||||
snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray);
|
snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray);
|
||||||
|
|
||||||
{
|
{
|
||||||
ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id];
|
ushort[5] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id, CLocation.component_id];
|
||||||
snake.snake_tmpl = launcher.manager.allocateTemplate(components);
|
snake.snake_tmpl = launcher.manager.allocateTemplate(components);
|
||||||
//CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation;
|
|
||||||
//*loc_comp = ivec2(2,2);
|
|
||||||
launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray);
|
launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id].staticArray);
|
snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id, CLocation.component_id].staticArray);
|
||||||
CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation;
|
CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation;
|
||||||
canim.frames = snake.snake_destroy_particle_frames;
|
canim.frames = snake.snake_destroy_particle_frames;
|
||||||
CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle;
|
CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle;
|
||||||
|
|
@ -813,7 +930,7 @@ void snakeStart()
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ushort[2] components = [CILocation.component_id, CApple.component_id];
|
ushort[3] components = [CILocation.component_id, CApple.component_id, CLocation.component_id];
|
||||||
snake.apple_tmpl = launcher.manager.allocateTemplate(components);
|
snake.apple_tmpl = launcher.manager.allocateTemplate(components);
|
||||||
snake.addApple();
|
snake.addApple();
|
||||||
}
|
}
|
||||||
|
|
@ -824,13 +941,6 @@ void snakeStart()
|
||||||
|
|
||||||
MoveSystem* move_system = launcher.manager.getSystem!MoveSystem();
|
MoveSystem* move_system = launcher.manager.getSystem!MoveSystem();
|
||||||
move_system.setTemplates();
|
move_system.setTemplates();
|
||||||
|
|
||||||
/*foreach(i; 0..10)
|
|
||||||
foreach(j; 0..10)
|
|
||||||
{
|
|
||||||
loc_compation = vec2(i*32+64,j*32+64);
|
|
||||||
launcher.manager.addEntity(simple.tmpl);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void snakeEnd()
|
void snakeEnd()
|
||||||
|
|
@ -839,39 +949,6 @@ void snakeEnd()
|
||||||
Mallocator.dispose(snake);
|
Mallocator.dispose(snake);
|
||||||
}
|
}
|
||||||
|
|
||||||
void snakeTool(vec2 position, Tool tool, int size)
|
|
||||||
{
|
|
||||||
switch(tool)
|
|
||||||
{
|
|
||||||
case Tool.entity_spawner:
|
|
||||||
{
|
|
||||||
EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate();
|
|
||||||
CLocation* location = tmpl.getComponent!CLocation;
|
|
||||||
if(location)
|
|
||||||
{
|
|
||||||
position.x += (randomf() - 0.5) * size;
|
|
||||||
position.y += (randomf() - 0.5) * size;
|
|
||||||
*location = position;
|
|
||||||
}
|
|
||||||
CILocation* ilocation = tmpl.getComponent!CILocation;
|
|
||||||
if(ilocation)
|
|
||||||
{
|
|
||||||
position.x += (randomf() - 0.5) * size;
|
|
||||||
position.y += (randomf() - 0.5) * size;
|
|
||||||
ivec2 ipos;
|
|
||||||
ipos.x = cast(int)(position.x / 16);
|
|
||||||
ipos.y = cast(int)(position.y / 16);
|
|
||||||
*ilocation = ipos;
|
|
||||||
if(snake.element(ipos).type != MapElement.Type.empty)return;
|
|
||||||
}
|
|
||||||
launcher.manager.addEntity(tmpl);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void snakeEvent(SDL_Event* event)
|
void snakeEvent(SDL_Event* event)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -881,16 +958,16 @@ bool snakeLoop()
|
||||||
{
|
{
|
||||||
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5;
|
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5;
|
||||||
|
|
||||||
/*if(launcher.show_demo_wnd)
|
// if(launcher.show_demo_wnd)
|
||||||
{
|
// {
|
||||||
igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
// igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
||||||
igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
|
// igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
|
||||||
if(igBegin("Snake",&launcher.show_demo_wnd,0))
|
// if(igBegin("Snake",&launcher.show_demo_wnd,0))
|
||||||
{
|
// {
|
||||||
|
|
||||||
}
|
// }
|
||||||
igEnd();
|
// igEnd();
|
||||||
}*/
|
// }
|
||||||
|
|
||||||
launcher.manager.begin();
|
launcher.manager.begin();
|
||||||
|
|
||||||
|
|
@ -901,9 +978,9 @@ bool snakeLoop()
|
||||||
if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3;
|
if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3;
|
||||||
else time += delta_time;
|
else time += delta_time;
|
||||||
|
|
||||||
while(time > 100)
|
while(time > 200)
|
||||||
{
|
{
|
||||||
time -= 100;
|
time -= 200;
|
||||||
|
|
||||||
launcher.manager.update("fixed");
|
launcher.manager.update("fixed");
|
||||||
}
|
}
|
||||||
|
|
@ -912,7 +989,16 @@ bool snakeLoop()
|
||||||
|
|
||||||
launcher.manager.end();
|
launcher.manager.end();
|
||||||
|
|
||||||
//snake.drawMap();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DemoCallbacks getSnakeDemo()
|
||||||
|
{
|
||||||
|
DemoCallbacks demo;
|
||||||
|
demo.register = &snakeRegister;
|
||||||
|
demo.initialize = &snakeStart;
|
||||||
|
demo.deinitialize = &snakeEnd;
|
||||||
|
demo.loop = &snakeLoop;
|
||||||
|
demo.tips = snake.tips;
|
||||||
|
return demo;
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load diff
255
demos/source/game_core/basic.d
Normal file
255
demos/source/game_core/basic.d
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
module game_core.basic;
|
||||||
|
|
||||||
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.attributes;
|
||||||
|
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
import gui.attributes;
|
||||||
|
|
||||||
|
import ecs_utils.utils;
|
||||||
|
|
||||||
|
import app : launcher;
|
||||||
|
|
||||||
|
import bindbc.sdl;
|
||||||
|
|
||||||
|
struct CLocation
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
vec2 value = vec2(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CScale
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;///use component as it value
|
||||||
|
|
||||||
|
vec2 value = vec2(16,16);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CRotation
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;///use component as it value
|
||||||
|
|
||||||
|
float value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CDepth
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
short value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CColor
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
@GUIColor uint value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CSelected
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
bool value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CInput
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CDamping
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
@GUIRange(0,9) byte value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CVelocity
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
vec2 value = vec2(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CVelocityFactor
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
vec2 value = vec2(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct DampingSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
const (Entity)[] entity;
|
||||||
|
@readonly CDamping[] damping;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
float[20] damp = 0;
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
foreach(i;0..20)
|
||||||
|
{
|
||||||
|
damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MoveSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!64;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
CLocation[] location;
|
||||||
|
@readonly CVelocity[] velocity;
|
||||||
|
@optional @readonly CVelocityFactor[] vel_factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
if(data.vel_factor)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.location[i] += data.velocity[i] * launcher.delta_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*System is responsible for movement of objects with CInput component.
|
||||||
|
*In this example every entity has same speed when using movement system.
|
||||||
|
*/
|
||||||
|
struct InputMovementSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
vec2 move_vector;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
//read only components can be marked with @readonly attribute or with const expression instead
|
||||||
|
const (CInput)[] input;
|
||||||
|
//components are treated as required by default
|
||||||
|
//CLocation[] locations;
|
||||||
|
CVelocity[] velocity;
|
||||||
|
//CTexture[] textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*onBegin gives opportunity to check keys once and call update on entities only when
|
||||||
|
*one key is pressed.
|
||||||
|
*/
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
move_vector = vec2(0,0);
|
||||||
|
if(launcher.getKeyState(SDL_SCANCODE_W))
|
||||||
|
{
|
||||||
|
move_vector += vec2(0,1);
|
||||||
|
}
|
||||||
|
else if(launcher.getKeyState(SDL_SCANCODE_S))
|
||||||
|
{
|
||||||
|
move_vector += vec2(0,-1);
|
||||||
|
}
|
||||||
|
if(launcher.getKeyState(SDL_SCANCODE_A))
|
||||||
|
{
|
||||||
|
move_vector += vec2(-1,0);
|
||||||
|
}
|
||||||
|
else if(launcher.getKeyState(SDL_SCANCODE_D))
|
||||||
|
{
|
||||||
|
move_vector += vec2(1,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(move_vector.x != 0 ||move_vector.y != 0)
|
||||||
|
{
|
||||||
|
move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//don't call system update because no key pressed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Update is called multiple times in one "manager.update()" call.
|
||||||
|
*Number of "onUpdate" calls is count of buffers which must be updated during pass.
|
||||||
|
*When multithreading is used, number of "onUpdate" calls can be greater due to fact that
|
||||||
|
*JobSystem can split buffers for better data packing.
|
||||||
|
*/
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
/*if(move_vector.x == 0)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.textures[i].coords = vec4(0*px,80*px,48*px,32*px);
|
||||||
|
}
|
||||||
|
//return;
|
||||||
|
}*/
|
||||||
|
//move every entity using movement vector
|
||||||
|
//if(move_vector.x != 0 || move_vector.y != 0)
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.velocity[i] += move_vector * launcher.delta_time * 0.005;
|
||||||
|
if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5;
|
||||||
|
else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5;
|
||||||
|
if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5;
|
||||||
|
else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5;
|
||||||
|
//data.locations[i].x += move_vector.x * launcher.delta_time * 0.25;
|
||||||
|
//data.locations[i].y += move_vector.y * launcher.delta_time * 0.25;
|
||||||
|
//if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px);
|
||||||
|
//else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px);
|
||||||
|
}
|
||||||
|
/*else
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
data.velocity[i] = vec2(0,0);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
1023
demos/source/game_core/collision.d
Normal file
1023
demos/source/game_core/collision.d
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -37,12 +37,17 @@ struct ECSJobUpdater
|
||||||
//pool.unregistExternalThread(thread_data);
|
//pool.unregistExternalThread(thread_data);
|
||||||
if(jobs)Mallocator.dispose(jobs);
|
if(jobs)Mallocator.dispose(jobs);
|
||||||
version(WebAssembly)pthread_key_delete(tls_key);
|
version(WebAssembly)pthread_key_delete(tls_key);
|
||||||
|
else version(Android)pthread_key_delete(tls_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
version(WebAssembly)
|
version(WebAssembly)
|
||||||
{
|
{
|
||||||
__gshared pthread_key_t tls_key;
|
__gshared pthread_key_t tls_key;
|
||||||
}
|
}
|
||||||
|
else version(Android)
|
||||||
|
{
|
||||||
|
__gshared pthread_key_t tls_key;
|
||||||
|
}
|
||||||
else static uint thread_id = 0;
|
else static uint thread_id = 0;
|
||||||
|
|
||||||
ThreadPool pool;
|
ThreadPool pool;
|
||||||
|
|
@ -105,6 +110,7 @@ struct ECSJobUpdater
|
||||||
void onCreate(uint threads_count)
|
void onCreate(uint threads_count)
|
||||||
{
|
{
|
||||||
version(WebAssembly)pthread_key_create(&tls_key, null);
|
version(WebAssembly)pthread_key_create(&tls_key, null);
|
||||||
|
else version(Android)pthread_key_create(&tls_key, null);
|
||||||
|
|
||||||
pool.initialize();
|
pool.initialize();
|
||||||
thread_data = pool.registerExternalThread();
|
thread_data = pool.registerExternalThread();
|
||||||
|
|
@ -116,6 +122,7 @@ struct ECSJobUpdater
|
||||||
uint getThreadID() @nogc nothrow
|
uint getThreadID() @nogc nothrow
|
||||||
{
|
{
|
||||||
version(WebAssembly)return cast(int)pthread_getspecific(tls_key);
|
version(WebAssembly)return cast(int)pthread_getspecific(tls_key);
|
||||||
|
else version(Android)return cast(int)pthread_getspecific(tls_key);
|
||||||
else return thread_id;
|
else return thread_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,6 +207,11 @@ struct ECSJobUpdater
|
||||||
}
|
}
|
||||||
else job.execute();
|
else job.execute();
|
||||||
}
|
}
|
||||||
|
else version(Android)
|
||||||
|
{
|
||||||
|
pthread_setspecific(tls_key, cast(void*)th_data.threadId);
|
||||||
|
job.execute();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updater.thread_id = th_data.threadId;
|
updater.thread_id = th_data.threadId;
|
||||||
|
|
|
||||||
616
demos/source/game_core/rendering.d
Normal file
616
demos/source/game_core/rendering.d
Normal file
|
|
@ -0,0 +1,616 @@
|
||||||
|
module game_core.rendering;
|
||||||
|
|
||||||
|
import bubel.ecs.attributes;
|
||||||
|
import bubel.ecs.core;
|
||||||
|
import bubel.ecs.std;
|
||||||
|
|
||||||
|
import ecs_utils.gfx.texture;
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
import game_core.basic;
|
||||||
|
|
||||||
|
void registerRenderingModule(EntityManager* manager)
|
||||||
|
{
|
||||||
|
manager.registerComponent!CLocation;
|
||||||
|
manager.registerComponent!CScale;
|
||||||
|
manager.registerComponent!CRotation;
|
||||||
|
manager.registerComponent!CDepth;
|
||||||
|
manager.registerComponent!CColor;
|
||||||
|
manager.registerComponent!CSelected;
|
||||||
|
manager.registerComponent!CTexCoords;
|
||||||
|
manager.registerComponent!CTexCoordsIndex;
|
||||||
|
manager.registerComponent!CMaterialIndex;
|
||||||
|
manager.registerComponent!CDrawDefault;
|
||||||
|
|
||||||
|
manager.registerSystem!DrawSystem(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CTexCoords
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;///use component as it value
|
||||||
|
|
||||||
|
vec4 value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CTexCoordsIndex
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
ushort value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CMaterialIndex
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
ushort value;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CDrawDefault
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TexCoordsManager
|
||||||
|
{
|
||||||
|
import bubel.ecs.vector;
|
||||||
|
import bubel.ecs.hash_map;
|
||||||
|
|
||||||
|
__gshared TexCoordsManager* instance = null;
|
||||||
|
|
||||||
|
static void initialize()
|
||||||
|
{
|
||||||
|
if(instance is null)instance = Mallocator.make!TexCoordsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy()
|
||||||
|
{
|
||||||
|
if(instance)Mallocator.dispose(instance);
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 get(ushort index)
|
||||||
|
{
|
||||||
|
if(index > coords.length)return vec4(0,0,1,1);
|
||||||
|
else return coords[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
ushort getCoordIndex(vec4 coords)
|
||||||
|
{
|
||||||
|
ushort ret = coords_map.get(coords, ushort.max);
|
||||||
|
if(ret != ushort.max)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
this.coords.add(coords);
|
||||||
|
coords_map.add(coords, cast(ushort)(this.coords.length - 1));
|
||||||
|
return cast(ushort)(this.coords.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector!vec4 coords;
|
||||||
|
HashMap!(vec4,ushort) coords_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DrawSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System!32;
|
||||||
|
|
||||||
|
import ecs_utils.gfx.renderer : Renderer;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
//uint thread_id;
|
||||||
|
uint job_id;
|
||||||
|
const(Entity)[] entity;
|
||||||
|
@readonly CLocation[] locations;
|
||||||
|
@readonly @optional CScale[] scale;
|
||||||
|
// @readonly CTexCoords[] texcoord;
|
||||||
|
@readonly @optional CTexCoords[] texcoord;
|
||||||
|
@readonly @optional CTexCoordsIndex[] texcoord_index;
|
||||||
|
@readonly @optional CRotation[] rotation;
|
||||||
|
@readonly @optional CDepth[] depth;
|
||||||
|
@readonly @optional CColor[] color;
|
||||||
|
@readonly @optional CMaterialIndex[] material;
|
||||||
|
@readonly @optional CDrawDefault[] draw_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer.DrawData default_data;
|
||||||
|
float color_time = 0;
|
||||||
|
uint select_color = 0;
|
||||||
|
|
||||||
|
bool onBegin()
|
||||||
|
{
|
||||||
|
import app : launcher;
|
||||||
|
color_time += launcher.delta_time * 0.001;
|
||||||
|
color_time = color_time - cast(int)(color_time*0.5)*2;
|
||||||
|
float ratio = color_time - cast(int)color_time;
|
||||||
|
if(color_time > 1)ratio = 1 - ratio;
|
||||||
|
uint multipler = cast(uint)(0x60 * ratio);
|
||||||
|
select_color = 0xA0A0A0A0 + cast(uint)(0x01010101 * multipler);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
import app : launcher;
|
||||||
|
|
||||||
|
if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached
|
||||||
|
Renderer.DrawData draw_data = default_data;
|
||||||
|
draw_data.thread_id = data.job_id;
|
||||||
|
|
||||||
|
if(launcher.show_filtered && launcher.filterEntity(data.entity[0]))
|
||||||
|
{
|
||||||
|
draw_data.color = select_color;
|
||||||
|
data.color = null;
|
||||||
|
}
|
||||||
|
//import std.stdio;
|
||||||
|
//writeln(data.draw_default);
|
||||||
|
//if(data.draw_default is null && data.texcoord is null && data.texcoord_index is null && !data.entity[0].hasComponent(CDrawDefault.component_id))return;
|
||||||
|
|
||||||
|
if(data.texcoord is null && data.texcoord_index is null && data.draw_default is null)return;
|
||||||
|
|
||||||
|
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
if(data.color)draw_data.color = data.color[i];
|
||||||
|
if(data.depth)draw_data.depth = data.depth[i];
|
||||||
|
if(data.rotation)draw_data.angle = data.rotation[i];
|
||||||
|
if(data.scale)draw_data.size = data.scale[i];
|
||||||
|
if(data.texcoord)draw_data.coords = data.texcoord[i];
|
||||||
|
else if(data.texcoord_index)draw_data.coords = TexCoordsManager.instance.get(data.texcoord_index[i]);
|
||||||
|
if(data.material)draw_data.material_id = data.material[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}//*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
ubyte mode;
|
||||||
|
if(data.scale)mode |= 0x01;
|
||||||
|
if(data.texcoord)mode |= 0x02;
|
||||||
|
if(data.texcoord_index)mode |= 0x04;
|
||||||
|
if(data.rotation)mode |= 0x08;
|
||||||
|
if(data.depth)mode |= 0x10;
|
||||||
|
if(data.color)mode |= 0x20;
|
||||||
|
|
||||||
|
if(launcher.show_filtered && launcher.filterEntity(data.entity[0]))
|
||||||
|
{
|
||||||
|
draw_data.color = select_color;
|
||||||
|
mode &= ~0x20;
|
||||||
|
//goto draw_nocolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0b000001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0b000010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b000011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0b001000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b001001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b001010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b001011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 0b010000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b010001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b010010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b010011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b011000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b011001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b011010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b011011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 0b100000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b100001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b100010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b100011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b101000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b101001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b101010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b101011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b110000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b110001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b110010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b110011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b111000:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b111001:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b111010:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0b111011:
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:break;
|
||||||
|
}//*/
|
||||||
|
/*
|
||||||
|
if(!data.color)
|
||||||
|
{
|
||||||
|
draw_nocolor:
|
||||||
|
if(!data.depth)
|
||||||
|
{
|
||||||
|
if(!data.rotation)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!data.rotation)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!data.depth)
|
||||||
|
{
|
||||||
|
if(!data.rotation)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.angle = data.rotation[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!data.rotation)
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach(i; 0..data.length)
|
||||||
|
{
|
||||||
|
draw_data.depth = data.depth[i];
|
||||||
|
draw_data.color = data.color[i];
|
||||||
|
draw_data.coords = data.texcoord[i];
|
||||||
|
draw_data.size = data.scale[i];
|
||||||
|
draw_data.position = data.locations[i];
|
||||||
|
launcher.renderer.draw(draw_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
20
demos/source/gui/attributes.d
Normal file
20
demos/source/gui/attributes.d
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
module gui.attributes;
|
||||||
|
|
||||||
|
enum GUIColor = "GUIColor";
|
||||||
|
|
||||||
|
struct GUIRange
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
}
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
float minf;
|
||||||
|
float maxf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,63 @@
|
||||||
module gui.components;
|
module gui.component;
|
||||||
|
|
||||||
|
import ecs_utils.utils;
|
||||||
|
|
||||||
struct ComponentGUI
|
struct ComponentGUI
|
||||||
{
|
{
|
||||||
|
const (char)* name;
|
||||||
}
|
void* data;
|
||||||
|
ushort component_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ComponentEditGUI
|
||||||
|
{
|
||||||
|
const (char)* name;
|
||||||
|
VariableGUI[] variables;
|
||||||
|
uint used;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VariableGUI
|
||||||
|
{
|
||||||
|
struct Int
|
||||||
|
{
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Float
|
||||||
|
{
|
||||||
|
float min;
|
||||||
|
float max;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Enum
|
||||||
|
{
|
||||||
|
const (char)[][] strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
byte_,
|
||||||
|
ubyte_,
|
||||||
|
short_,
|
||||||
|
ushort_,
|
||||||
|
int_,
|
||||||
|
uint_,
|
||||||
|
float_,
|
||||||
|
enum_,
|
||||||
|
color,
|
||||||
|
vec2,
|
||||||
|
ivec2,
|
||||||
|
vec4,
|
||||||
|
ivec4
|
||||||
|
}
|
||||||
|
Type type;
|
||||||
|
const (char)* name;
|
||||||
|
ushort offset;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
Int int_;
|
||||||
|
Float float_;
|
||||||
|
Enum enum_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,55 @@ import app;
|
||||||
|
|
||||||
import cimgui.cimgui;
|
import cimgui.cimgui;
|
||||||
|
|
||||||
|
import bubel.ecs.entity;
|
||||||
|
import bubel.ecs.manager;
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
import bubel.ecs.system;
|
import bubel.ecs.system;
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
import bubel.ecs.entity;
|
|
||||||
|
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
import gui.attributes;
|
||||||
|
import gui.component;
|
||||||
import gui.system;
|
import gui.system;
|
||||||
import gui.template_;
|
import gui.template_;
|
||||||
|
|
||||||
|
import std.traits;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
struct GUIManager
|
struct GUIManager
|
||||||
{
|
{
|
||||||
Vector!SystemGUI systems;
|
Vector!SystemGUI systems;
|
||||||
|
Vector!ComponentGUI components;
|
||||||
Vector!TemplateGUI templates;
|
Vector!TemplateGUI templates;
|
||||||
|
Vector!ComponentEditGUI edit_components;
|
||||||
|
Vector!bool filter;
|
||||||
|
Vector!ushort filter_list;
|
||||||
|
|
||||||
uint selected_tempalte = 0;
|
int selected_template = 0;
|
||||||
|
int selected_component = 0;
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectTemplate(int id)
|
||||||
|
{
|
||||||
|
if(templates.length == 0)return;
|
||||||
|
selected_template = id;
|
||||||
|
while(selected_template < 0)selected_template += cast(int)templates.length;
|
||||||
|
while(selected_template >= templates.length)selected_template -= cast(int)templates.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectComponent(int id)
|
||||||
|
{
|
||||||
|
if(components.length == 0)return;
|
||||||
|
selected_component = id;
|
||||||
|
while(selected_component < 0)selected_component += cast(int)components.length;
|
||||||
|
while(selected_component >= components.length)selected_component -= cast(int)components.length;
|
||||||
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
|
|
@ -27,23 +60,51 @@ struct GUIManager
|
||||||
{
|
{
|
||||||
launcher.manager.freeTemplate(tmpl.tmpl);
|
launcher.manager.freeTemplate(tmpl.tmpl);
|
||||||
}
|
}
|
||||||
|
foreach(comp; components)
|
||||||
|
{
|
||||||
|
free(comp.data);
|
||||||
|
}
|
||||||
|
foreach(ref comp; edit_components)
|
||||||
|
{
|
||||||
|
if(comp.variables)Mallocator.dispose(comp.variables);
|
||||||
|
comp.variables = null;
|
||||||
|
comp.used = 0;
|
||||||
|
comp.name = null;
|
||||||
|
}
|
||||||
|
foreach(ref comp; filter)
|
||||||
|
{
|
||||||
|
comp = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_list.clear();
|
||||||
systems.clear();
|
systems.clear();
|
||||||
templates.clear();
|
templates.clear();
|
||||||
selected_tempalte = 0;
|
components.clear();
|
||||||
|
selected_template = 0;
|
||||||
|
selected_component = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityTemplate* getSelectedTemplate()
|
EntityTemplate* getSelectedTemplate()
|
||||||
{
|
{
|
||||||
if(templates.length > selected_tempalte)return templates[selected_tempalte].tmpl;
|
if(templates.length > selected_template)return templates[selected_template].tmpl;
|
||||||
else return null;
|
else return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ComponentRef getSelectedComponent()
|
||||||
|
{
|
||||||
|
if(components.length > selected_component)return ComponentRef(components[selected_component].data, components[selected_component].component_id);
|
||||||
|
else return ComponentRef(null, ushort.max);
|
||||||
|
}
|
||||||
|
|
||||||
void addSystem(ushort id, const (char)* name, bool enabled = true)
|
void addSystem(ushort id, const (char)* name, bool enabled = true)
|
||||||
{
|
{
|
||||||
|
foreach(ref sys; systems)
|
||||||
|
{
|
||||||
|
if(sys.id == id)return;
|
||||||
|
}
|
||||||
System* system = launcher.manager.getSystem(id);
|
System* system = launcher.manager.getSystem(id);
|
||||||
//const (char)* name =
|
//const (char)* name =
|
||||||
systems.add(SystemGUI(name,system,enabled));
|
systems.add(SystemGUI(name,id,enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addTemplate(ushort[] components, const (char)* name)
|
void addTemplate(ushort[] components, const (char)* name)
|
||||||
|
|
@ -56,43 +117,394 @@ struct GUIManager
|
||||||
templates.add(TemplateGUI(name, tmpl));
|
templates.add(TemplateGUI(name, tmpl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void addComponent(ComponentRef comp, const (char)* name)
|
||||||
|
// {
|
||||||
|
// uint size = EntityManager.instance.components[comp.component_id].size;
|
||||||
|
// void* data = malloc(size);
|
||||||
|
// memcpy(data, comp.ptr, size);
|
||||||
|
// components.add(ComponentGUI(name, data, comp.component_id));
|
||||||
|
// }
|
||||||
|
|
||||||
|
void addComponent(T)(T comp, const (char)* name)
|
||||||
|
{
|
||||||
|
static assert(hasStaticMember!(T,"component_id"));
|
||||||
|
uint size = EntityManager.instance.components[comp.component_id].size;
|
||||||
|
void* data = malloc(size);
|
||||||
|
memcpy(data, &comp, size);
|
||||||
|
components.add(ComponentGUI(name, data, comp.component_id));
|
||||||
|
|
||||||
|
if(edit_components.length <= comp.component_id)
|
||||||
|
{
|
||||||
|
edit_components.length = comp.component_id+1;//.extend(comp.component_id + 1);
|
||||||
|
}
|
||||||
|
//edit_components[comp.component_id] = ComponentEditGUI(name);
|
||||||
|
if(edit_components[comp.component_id].variables)return;
|
||||||
|
ComponentEditGUI comp_edit;
|
||||||
|
comp_edit.name = T.stringof;
|
||||||
|
//enum fields = __traits(allMembers, T);
|
||||||
|
alias fields = FieldNameTuple!T;
|
||||||
|
//pragma(msg,fields);
|
||||||
|
comp_edit.variables = Mallocator.makeArray!VariableGUI(fields.length);
|
||||||
|
foreach(member_str; fields)
|
||||||
|
{
|
||||||
|
alias member = __traits(getMember, T, member_str);
|
||||||
|
alias member_type = typeof(member);
|
||||||
|
//pragma(msg,member);
|
||||||
|
//pragma(msg,member_type);
|
||||||
|
//pragma(msg,__traits(getMember, T, member).offsetof);
|
||||||
|
ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof;
|
||||||
|
static if(is(member_type == vec2))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec2,member_str,offset);
|
||||||
|
}
|
||||||
|
else static if(is(member_type == ivec2))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec2,member_str,offset);
|
||||||
|
}
|
||||||
|
else static if(is(member_type == vec4))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec4,member_str,offset);
|
||||||
|
}
|
||||||
|
else static if(is(member_type == ivec4))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec4,member_str,offset);
|
||||||
|
}
|
||||||
|
else static if(__traits(isIntegral,member_type))
|
||||||
|
{
|
||||||
|
static if(__traits(isUnsigned, member_type))
|
||||||
|
{
|
||||||
|
static if(hasUDA!(member,GUIColor))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.color,member_str,offset);
|
||||||
|
}
|
||||||
|
else switch(member_type.sizeof)
|
||||||
|
{
|
||||||
|
case 1: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ubyte_,member_str,offset);break;
|
||||||
|
case 2: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ushort_,member_str,offset);break;
|
||||||
|
case 4: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.uint_,member_str,offset);break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
static if(hasUDA!(member,GUIRange))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = 0;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = int.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(member_type.sizeof)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.byte_,member_str,offset);
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = byte.min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = byte.max;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.short_,member_str,offset);
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = short.min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = short.max;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.int_,member_str,offset);
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = int.min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = int.max;
|
||||||
|
break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
static if(hasUDA!(member,GUIRange))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max;
|
||||||
|
}
|
||||||
|
/*{
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.min = int.min;
|
||||||
|
comp_edit.variables[comp_edit.used-1].int_.max = int.max;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else static if(__traits(isScalar,member_type))
|
||||||
|
{
|
||||||
|
switch(member_type.sizeof)
|
||||||
|
{
|
||||||
|
case 4:comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.float_,member_str,offset);break;
|
||||||
|
case 8:
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
static if(hasUDA!(member,GUIRange))
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRange)[0].minf;
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRange)[1].maxf;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.min = -float.max;
|
||||||
|
comp_edit.variables[comp_edit.used-1].float_.max = float.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edit_components[comp.component_id] = comp_edit;
|
||||||
|
}
|
||||||
|
|
||||||
void gui()
|
void gui()
|
||||||
{
|
{
|
||||||
if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding))
|
if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
{
|
{
|
||||||
bool true_ = true;
|
//bool true_ = true;
|
||||||
igIndent(8);
|
igIndent(8);
|
||||||
foreach(ref SystemGUI system;systems)
|
foreach(ref SystemGUI system;systems)
|
||||||
{
|
{
|
||||||
if(igCheckbox(system.name,&system.enabled))
|
if(igCheckbox(system.name,&system.enabled))
|
||||||
{
|
{
|
||||||
if(system.enabled)system.system.enable();
|
System* sys = launcher.manager.getSystem(system.id);
|
||||||
else system.system.disable();
|
if(system.enabled)sys.enable();
|
||||||
|
else sys.disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
igUnindent(8);
|
igUnindent(8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void toolGui()
|
static vec4 colorUintToVec4(uint color)
|
||||||
{
|
{
|
||||||
if(templates.length)
|
// color = *cast(uint*)(comp_ptr+var.offset);
|
||||||
|
return vec4(cast(float)(color & 0xFF) / 255,
|
||||||
|
cast(float)(color >> 8 & 0xFF) / 255,
|
||||||
|
cast(float)(color >> 16 & 0xFF) / 255,
|
||||||
|
cast(float)(color >> 24 & 0xFF) / 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint colorVec4ToUint(vec4 color)
|
||||||
|
{
|
||||||
|
return cast(uint)(color.x * 255) |
|
||||||
|
cast(uint)(color.y * 255) << 8 |
|
||||||
|
cast(uint)(color.z * 255) << 16 |
|
||||||
|
cast(uint)(color.w * 255) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool igDragScalarClamp(const(char)* label, ImGuiDataType data_type, void* v, float v_speed, const(void)* v_min, const(void)* v_max, const(char)* format, float power)
|
||||||
|
{
|
||||||
|
ubyte[8] v_backup;// = *v;
|
||||||
|
final switch(data_type)
|
||||||
{
|
{
|
||||||
if(igBeginCombo("Template",templates[selected_tempalte].name,0))
|
case ImGuiDataType_S8:memcpy(v_backup.ptr, v, 1);break;
|
||||||
{
|
case ImGuiDataType_S16:memcpy(v_backup.ptr, v, 2);break;
|
||||||
foreach(i, tmpl; templates)
|
case ImGuiDataType_S32:memcpy(v_backup.ptr, v, 4);break;
|
||||||
{
|
case ImGuiDataType_U8:memcpy(v_backup.ptr, v, 1);break;
|
||||||
if(igSelectable(tmpl.name,false,0,ImVec2(0,0)))
|
case ImGuiDataType_U16:memcpy(v_backup.ptr, v, 2);break;
|
||||||
{
|
case ImGuiDataType_U32:memcpy(v_backup.ptr, v, 4);break;
|
||||||
selected_tempalte = cast(uint)i;
|
case ImGuiDataType_Float:memcpy(v_backup.ptr, v, 4);break;
|
||||||
}
|
|
||||||
}
|
|
||||||
igEndCombo();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
if (!igDragScalar(label, data_type, v, v_speed, v_min, v_max, format, power))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
final switch(data_type)
|
||||||
{
|
{
|
||||||
if(igBeginCombo("Template",null,0))igEndCombo();
|
case ImGuiDataType_S8:
|
||||||
|
if(*cast(byte*)v < *cast(byte*)v_min)*cast(byte*)v = *cast(byte*)v_min;
|
||||||
|
else if(*cast(byte*)v > *cast(byte*)v_max)*cast(byte*)v = *cast(byte*)v_max;
|
||||||
|
return *cast(byte*)v != *cast(byte*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_S16:
|
||||||
|
if(*cast(short*)v < *cast(short*)v_min)*cast(short*)v = *cast(short*)v_min;
|
||||||
|
else if(*cast(short*)v > *cast(short*)v_max)*cast(short*)v = *cast(short*)v_max;
|
||||||
|
return *cast(short*)v != *cast(short*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_S32:
|
||||||
|
if(*cast(int*)v < *cast(int*)v_min)*cast(int*)v = *cast(int*)v_min;
|
||||||
|
else if(*cast(int*)v > *cast(int*)v_max)*cast(int*)v = *cast(int*)v_max;
|
||||||
|
return *cast(int*)v != *cast(int*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_U8:
|
||||||
|
if(*cast(ubyte*)v < *cast(ubyte*)v_min)*cast(ubyte*)v = *cast(ubyte*)v_min;
|
||||||
|
else if(*cast(ubyte*)v > *cast(ubyte*)v_max)*cast(ubyte*)v = *cast(ubyte*)v_max;
|
||||||
|
return *cast(ubyte*)v != *cast(ubyte*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_U16:
|
||||||
|
if(*cast(ushort*)v < *cast(ushort*)v_min)*cast(ushort*)v = *cast(ushort*)v_min;
|
||||||
|
else if(*cast(ushort*)v > *cast(ushort*)v_max)*cast(ushort*)v = *cast(ushort*)v_max;
|
||||||
|
return *cast(ushort*)v != *cast(ushort*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_U32:
|
||||||
|
if(*cast(uint*)v < *cast(uint*)v_min)*cast(uint*)v = *cast(uint*)v_min;
|
||||||
|
else if(*cast(uint*)v > *cast(uint*)v_max)*cast(uint*)v = *cast(uint*)v_max;
|
||||||
|
return *cast(uint*)v != *cast(uint*)v_backup.ptr;
|
||||||
|
case ImGuiDataType_Float:
|
||||||
|
if(*cast(float*)v < *cast(float*)v_min)*cast(float*)v = *cast(float*)v_min;
|
||||||
|
else if(*cast(float*)v > *cast(float*)v_max)*cast(float*)v = *cast(float*)v_max;
|
||||||
|
return *cast(float*)v != *cast(float*)v_backup.ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void componentGUI(ushort comp_id, void* data_ptr)
|
||||||
|
{
|
||||||
|
vec4 color;
|
||||||
|
if(comp_id >= edit_components.length)return;
|
||||||
|
if(edit_components[comp_id].used)
|
||||||
|
{
|
||||||
|
if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
igIndent(8);
|
||||||
|
foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used])
|
||||||
|
{
|
||||||
|
igPushIDPtr(&var);
|
||||||
|
switch(var.type)
|
||||||
|
{
|
||||||
|
case VariableGUI.Type.byte_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.ubyte_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.short_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.ushort_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_U16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.int_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.uint_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.float_:
|
||||||
|
igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.color:
|
||||||
|
color = colorUintToVec4(*cast(uint*)(data_ptr+var.offset));
|
||||||
|
if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None))
|
||||||
|
*cast(uint*)(data_ptr+var.offset) = colorVec4ToUint(color);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.vec2:
|
||||||
|
igDragFloat2(var.name, (cast(float*)(data_ptr+var.offset))[0..2], 0.1, -float.max, float.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.ivec2:
|
||||||
|
igDragInt2(var.name, (cast(int*)(data_ptr+var.offset))[0..2], 0.1, int.min, int.max, null);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.vec4:
|
||||||
|
igDragFloat4(var.name, (cast(float*)(data_ptr+var.offset))[0..4], 0.1, -float.max, float.max, null, 1);
|
||||||
|
break;
|
||||||
|
case VariableGUI.Type.ivec4:
|
||||||
|
igDragInt4(var.name, (cast(int*)(data_ptr+var.offset))[0..4], 0.1, int.min, int.max, null);
|
||||||
|
break;
|
||||||
|
default:break;
|
||||||
|
}
|
||||||
|
igPopID();
|
||||||
|
}
|
||||||
|
//igPopID();
|
||||||
|
igUnindent(8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void entityComponentsGUI()
|
||||||
|
{
|
||||||
|
if(selected_template >= templates.length)return;
|
||||||
|
EntityTemplate* tmpl = templates[selected_template].tmpl;
|
||||||
|
EntityManager.EntityInfo* info = tmpl.info;
|
||||||
|
foreach(comp_id; info.components)
|
||||||
|
{
|
||||||
|
void* data_ptr = tmpl.entity_data.ptr;
|
||||||
|
void* comp_ptr = data_ptr + info.tmpl_deltas[comp_id];
|
||||||
|
componentGUI(comp_id, comp_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void toolGui()
|
||||||
|
{
|
||||||
|
ImGuiStyle * style = igGetStyle();
|
||||||
|
ImVec4 col = style.Colors[ImGuiCol_Header];
|
||||||
|
style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg];
|
||||||
|
//style.
|
||||||
|
//ImDrawList* draw_list = igGetWindowDrawList();
|
||||||
|
final switch(launcher.used_tool)
|
||||||
|
{
|
||||||
|
case Tool.entity_spawner:
|
||||||
|
if(templates.length)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if(igListBoxHeaderInt("Template",cast(int)templates.length,cast(int)templates.length))
|
||||||
|
{
|
||||||
|
foreach(i, tmpl; templates)
|
||||||
|
{
|
||||||
|
if(igSelectable(tmpl.name,selected_template == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0)))
|
||||||
|
{
|
||||||
|
selected_template = cast(uint)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
igListBoxFooter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Select entity to spawn (SHIFT + Scroll)");
|
||||||
|
}
|
||||||
|
style.Colors[ImGuiCol_Header] = col;
|
||||||
|
entityComponentsGUI();
|
||||||
|
break;
|
||||||
|
case Tool.component_manipulator:
|
||||||
|
if(components.length)
|
||||||
|
{
|
||||||
|
if(igListBoxHeaderInt("Components",cast(int)components.length,cast(int)components.length))
|
||||||
|
{
|
||||||
|
foreach(i, comp; components)
|
||||||
|
{
|
||||||
|
if(igSelectable(comp.name,selected_component == i,0,ImVec2(0,0)))
|
||||||
|
{
|
||||||
|
selected_component = cast(uint)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
igListBoxFooter();
|
||||||
|
}
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)");
|
||||||
|
}
|
||||||
|
style.Colors[ImGuiCol_Header] = col;
|
||||||
|
if(selected_component < components.length)componentGUI(components[selected_component].component_id, components[selected_component].data);
|
||||||
|
break;
|
||||||
|
case Tool.selector:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
style.Colors[ImGuiCol_Header] = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void genFilterList()
|
||||||
|
{
|
||||||
|
filter_list.clear();
|
||||||
|
foreach(i, comp; filter)
|
||||||
|
{
|
||||||
|
if(comp)
|
||||||
|
{
|
||||||
|
filter_list.add(cast(ushort)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void filterGUI()
|
||||||
|
{
|
||||||
|
ImGuiStyle * style = igGetStyle();
|
||||||
|
ImVec4 col = style.Colors[ImGuiCol_Header];
|
||||||
|
style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg];
|
||||||
|
|
||||||
|
if(filter.length < edit_components.length)filter.length(edit_components.length);
|
||||||
|
|
||||||
|
int length = 0;
|
||||||
|
foreach(comp; edit_components)
|
||||||
|
{
|
||||||
|
if(comp.name !is null)length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(length && igListBoxHeaderInt("Components##FilterComponents",cast(int)length,cast(int)length))
|
||||||
|
{
|
||||||
|
foreach(i, ref comp; edit_components)
|
||||||
|
{
|
||||||
|
if(comp.name is null)continue;
|
||||||
|
if(igSelectableBoolPtr(comp.name,&filter[i],0,ImVec2(0,0)))
|
||||||
|
{
|
||||||
|
genFilterList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
igListBoxFooter();
|
||||||
|
}
|
||||||
|
if(igIsItemHovered(0))igSetTooltip("Select components to filter while tool work.\nComponents are only changed for filtered entities.");
|
||||||
|
|
||||||
|
style.Colors[ImGuiCol_Header] = col;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,8 @@ import bubel.ecs.system;
|
||||||
struct SystemGUI
|
struct SystemGUI
|
||||||
{
|
{
|
||||||
const (char)* name;
|
const (char)* name;
|
||||||
System* system;
|
//System* system;
|
||||||
|
ushort id;
|
||||||
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
}
|
}
|
||||||
53
demos/source/gui/tool_circle.d
Normal file
53
demos/source/gui/tool_circle.d
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
module gui.tool_circle;
|
||||||
|
|
||||||
|
import ecs_utils.gfx.buffer;
|
||||||
|
import ecs_utils.gfx.shader;
|
||||||
|
import ecs_utils.gfx.config;
|
||||||
|
import ecs_utils.gfx.renderer;
|
||||||
|
|
||||||
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
|
struct ToolCircle
|
||||||
|
{
|
||||||
|
//Buffer vbo;
|
||||||
|
//Buffer ibo;
|
||||||
|
|
||||||
|
uint material_id = 1;
|
||||||
|
uint mesh_id = 0;
|
||||||
|
|
||||||
|
/*/void generate()
|
||||||
|
{
|
||||||
|
ushort[]
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void draw(Renderer* renderer, vec2 position, float size, float edge = 1)
|
||||||
|
{
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
position = position * renderer.view_size + renderer.view_pos;
|
||||||
|
vec2 sizes = renderer.view_size * size;
|
||||||
|
vec2 sizes2 = vec2(edge,0);
|
||||||
|
|
||||||
|
import core.stdc.string;
|
||||||
|
ubyte[32] uniform_block;
|
||||||
|
void* ptr = uniform_block.ptr;
|
||||||
|
*cast(float*)(ptr) = sizes.x;
|
||||||
|
*cast(float*)(ptr+4) = 0;
|
||||||
|
*cast(float*)(ptr+8) = 0;
|
||||||
|
*cast(float*)(ptr+12) = sizes.y;
|
||||||
|
memcpy(ptr+16,position.data.ptr,8);
|
||||||
|
memcpy(ptr+24,sizes2.data.ptr,8);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
GfxConfig.meshes[mesh_id].bind();
|
||||||
|
GfxConfig.materials[material_id].bind();
|
||||||
|
GfxConfig.materials[material_id].pushBindings();
|
||||||
|
GfxConfig.materials[material_id].pushUniforms(uniform_block.ptr);
|
||||||
|
//glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,14 +15,13 @@
|
||||||
"../external/sources"
|
"../external/sources"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bindbc-sdl":"0.13.0",
|
"bindbc-sdl":"0.19.0",
|
||||||
"ecs":{"path":"../../"}
|
"ecs":{"path":"../../"}
|
||||||
},
|
},
|
||||||
"versions": [
|
"versions": [
|
||||||
"BindSDL_Image",
|
"BindSDL_Image",
|
||||||
"SDL_2010"
|
"SDL_2010"
|
||||||
],
|
],
|
||||||
|
|
||||||
"configurations" : [
|
"configurations" : [
|
||||||
{
|
{
|
||||||
"name" : "default",
|
"name" : "default",
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,12 @@ module ecs_utils.gfx.buffer;
|
||||||
|
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
|
|
||||||
import glad.gl.gl;
|
//import glad.gl.gl;
|
||||||
import glad.gl.gles2;
|
//import glad.gl.gles2;
|
||||||
|
|
||||||
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
|
|
@ -64,13 +68,13 @@ struct Buffer
|
||||||
void map(BindTarget target) nothrow
|
void map(BindTarget target) nothrow
|
||||||
{
|
{
|
||||||
bind(target);
|
bind(target);
|
||||||
data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY);
|
version(Android){}else version(WebAssembly){}else data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void map(uint offset, uint size, BindTarget target, uint flags = MapFlagBits.write | MapFlagBits.flush_explict | MapFlagBits.invalidate_buffer) nothrow
|
void map(uint offset, uint size, BindTarget target, uint flags = MapFlagBits.write | MapFlagBits.flush_explict | MapFlagBits.invalidate_buffer) nothrow
|
||||||
{
|
{
|
||||||
bind(target);
|
bind(target);
|
||||||
data.map_ptr = glMapBufferRange(target,offset,size,flags);
|
version(Android){}else data.map_ptr = glMapBufferRange(target,offset,size,flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush(uint offset, uint size, BindTarget target) nothrow
|
void flush(uint offset, uint size, BindTarget target) nothrow
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
||||||
|
|
||||||
import ecs_utils.gfx.shader;
|
import ecs_utils.gfx.shader;
|
||||||
|
|
||||||
import glad.gl.gl;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
//import mutils.serializer.json;
|
//import mutils.serializer.json;
|
||||||
|
|
||||||
|
|
@ -76,6 +78,25 @@ struct Material
|
||||||
|
|
||||||
void bind() nothrow
|
void bind() nothrow
|
||||||
{
|
{
|
||||||
|
final switch(data.blend_mode)
|
||||||
|
{
|
||||||
|
case BlendMode.mixed:
|
||||||
|
glDepthMask(0);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
case BlendMode.opaque:
|
||||||
|
glDepthMask(1);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
break;
|
||||||
|
case BlendMode.additive:
|
||||||
|
glDepthMask(0);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
//glBlendFunc(GL_ONE, GL_ONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
glUseProgram(data.modules[0].gl_handle);
|
glUseProgram(data.modules[0].gl_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
||||||
|
|
||||||
import ecs_utils.gfx.buffer;
|
import ecs_utils.gfx.buffer;
|
||||||
|
|
||||||
import glad.gl.gl;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
//import mutils.serializer.json;
|
//import mutils.serializer.json;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import ecs_utils.math.vector;
|
||||||
import bubel.ecs.block_allocator;
|
import bubel.ecs.block_allocator;
|
||||||
import bubel.ecs.vector;
|
import bubel.ecs.vector;
|
||||||
version(WebAssembly)import glad.gl.gles2;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
else import glad.gl.gl;
|
else import glad.gl.gl;
|
||||||
|
|
||||||
version = ver1;
|
version = ver1;
|
||||||
|
|
@ -66,8 +67,10 @@ struct Renderer
|
||||||
enum max_items = batch_size;//963;
|
enum max_items = batch_size;//963;
|
||||||
byte[] batch_vertices;
|
byte[] batch_vertices;
|
||||||
ushort[] batch_indices;
|
ushort[] batch_indices;
|
||||||
void* memory;
|
void* memory = null;
|
||||||
uint items = 0;
|
uint items = 0;
|
||||||
|
uint material_id;
|
||||||
|
uint texture_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex* get_block_mutex;
|
Mutex* get_block_mutex;
|
||||||
|
|
@ -127,11 +130,11 @@ struct Renderer
|
||||||
block_stack_mutex.unlock();*/
|
block_stack_mutex.unlock();*/
|
||||||
foreach(ref Thread thread; threads)
|
foreach(ref Thread thread; threads)
|
||||||
{
|
{
|
||||||
foreach(VertexBlock block; thread.blocks)
|
foreach(VertexBlock block; thread.filled_blocks)
|
||||||
{
|
{
|
||||||
allocator.freeBlock(block.memory);
|
allocator.freeBlock(block.memory);
|
||||||
}
|
}
|
||||||
thread.blocks.clear();
|
thread.filled_blocks.clear();
|
||||||
}
|
}
|
||||||
render_blocks = 0;
|
render_blocks = 0;
|
||||||
current_block = 0;
|
current_block = 0;
|
||||||
|
|
@ -143,13 +146,13 @@ struct Renderer
|
||||||
{
|
{
|
||||||
foreach(ref Thread thread; threads)
|
foreach(ref Thread thread; threads)
|
||||||
{
|
{
|
||||||
foreach(VertexBlock block; thread.blocks)
|
foreach(VertexBlock block; thread.filled_blocks)
|
||||||
{
|
{
|
||||||
uint items = block.items;
|
uint items = block.items;
|
||||||
if(items + item_id >= MaxObjects)items = MaxObjects - item_id;
|
if(items + item_id >= MaxObjects)items = MaxObjects - item_id;
|
||||||
batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr);
|
batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr);
|
||||||
batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr);
|
batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr);
|
||||||
draw_list.add(DrawCall(item_id,items));
|
draw_list.add(DrawCall(block.texture_id,block.material_id,item_id,items));
|
||||||
item_id += items;
|
item_id += items;
|
||||||
}
|
}
|
||||||
//thread.blocks.clear();
|
//thread.blocks.clear();
|
||||||
|
|
@ -172,17 +175,38 @@ struct Renderer
|
||||||
foreach(i, ref Thread thread; threads)
|
foreach(i, ref Thread thread; threads)
|
||||||
{
|
{
|
||||||
//pushBlock(thread.block);
|
//pushBlock(thread.block);
|
||||||
thread.blocks.add(thread.block);
|
foreach(ref block; thread.blocks)
|
||||||
thread.block = getBlock();
|
{
|
||||||
|
if(block.items > 0)
|
||||||
|
{
|
||||||
|
thread.filled_blocks.add(block);
|
||||||
|
block.items = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//thread.blocks = getBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DrawData
|
||||||
|
{
|
||||||
|
Texture texture;
|
||||||
|
vec2 position;
|
||||||
|
vec2 size;
|
||||||
|
vec4 coords;
|
||||||
|
short depth = 0;
|
||||||
|
uint color = uint.max;
|
||||||
|
float angle = 0;
|
||||||
|
uint material_id = 0;
|
||||||
|
uint mesh_id = 0;
|
||||||
|
uint thread_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct Thread
|
struct Thread
|
||||||
{
|
{
|
||||||
//Vector!VertexBlock block;
|
//Vector!VertexBlock block;
|
||||||
RenderData[] render_list;
|
RenderData[] render_list;
|
||||||
VertexBlock block;
|
VertexBlock[] blocks;
|
||||||
Vector!VertexBlock blocks;
|
Vector!VertexBlock filled_blocks;
|
||||||
}
|
}
|
||||||
Thread[] threads;
|
Thread[] threads;
|
||||||
|
|
||||||
|
|
@ -224,6 +248,8 @@ struct Renderer
|
||||||
|
|
||||||
struct DrawCall
|
struct DrawCall
|
||||||
{
|
{
|
||||||
|
uint texture_id;
|
||||||
|
uint material_id;
|
||||||
uint start;
|
uint start;
|
||||||
uint count;
|
uint count;
|
||||||
}
|
}
|
||||||
|
|
@ -248,6 +274,7 @@ struct Renderer
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
|
import ecs_utils.gfx.config;
|
||||||
//this.technique = __ecs_used_technique;
|
//this.technique = __ecs_used_technique;
|
||||||
__initialize(this);
|
__initialize(this);
|
||||||
|
|
||||||
|
|
@ -260,7 +287,8 @@ struct Renderer
|
||||||
threads = Mallocator.makeArray!Thread(32);
|
threads = Mallocator.makeArray!Thread(32);
|
||||||
foreach(ref Thread thread;threads)
|
foreach(ref Thread thread;threads)
|
||||||
{
|
{
|
||||||
thread.block = getBlock();
|
//thread.blocks = getBlock();
|
||||||
|
thread.blocks = Mallocator.makeArray!VertexBlock(GfxConfig.materials.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -416,13 +444,15 @@ struct Renderer
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0)
|
//void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0)
|
||||||
|
void draw(scope ref const(DrawData) data)
|
||||||
{
|
{
|
||||||
if(prepared_items >= MaxObjects)return;
|
if(prepared_items >= MaxObjects)return;
|
||||||
__draw(this,tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id);
|
__draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id)
|
//private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id)
|
||||||
|
private static void __draw_sdl(ref Renderer this_, scope ref const(DrawData) data)
|
||||||
{
|
{
|
||||||
/*with(this_)
|
/*with(this_)
|
||||||
{
|
{
|
||||||
|
|
@ -442,22 +472,25 @@ struct Renderer
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id)
|
// private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id)
|
||||||
|
private static void __draw_gl(ref Renderer this_, scope ref const(DrawData) data)
|
||||||
{
|
{
|
||||||
//import core.stdc.string;
|
//import core.stdc.string;
|
||||||
with(this_)
|
with(this_)
|
||||||
{
|
{
|
||||||
//pos += view_pos;
|
//pos += view_pos;
|
||||||
size.x *= view_size.x;
|
vec2 pos = void;
|
||||||
size.y *= view_size.y;
|
vec2 size = void;
|
||||||
pos.x = pos.x * view_size.x + view_pos.x;
|
size.x = data.size.x * view_size.x;
|
||||||
pos.y = pos.y * view_size.y + view_pos.y;//*/
|
size.y = data.size.y * view_size.y;
|
||||||
|
pos.x = data.position.x * view_size.x + view_pos.x;
|
||||||
|
pos.y = data.position.y * view_size.y + view_pos.y;//*/
|
||||||
|
|
||||||
/*version(ver6)void* ptr = ubos[0].mappedPointer() + data_index;
|
/*version(ver6)void* ptr = ubos[0].mappedPointer() + data_index;
|
||||||
else void* ptr = uniform_block.ptr + data_index;*/
|
else void* ptr = uniform_block.ptr + data_index;*/
|
||||||
if(data_ptr is null)return;
|
if(data_ptr is null)return;
|
||||||
void* ptr = data_ptr + data_index;
|
void* ptr = data_ptr + data_index;
|
||||||
if(angle == 0)
|
if(data.angle == 0)
|
||||||
{
|
{
|
||||||
*cast(float*)ptr = size.x;
|
*cast(float*)ptr = size.x;
|
||||||
*cast(float*)(ptr+4) = 0;
|
*cast(float*)(ptr+4) = 0;
|
||||||
|
|
@ -467,8 +500,8 @@ struct Renderer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//import core.stdc.math;
|
//import core.stdc.math;
|
||||||
float sinn = sinf(angle);
|
float sinn = sinf(data.angle);
|
||||||
float coss = cosf(angle);
|
float coss = cosf(data.angle);
|
||||||
*cast(float*)ptr = coss * size.x;
|
*cast(float*)ptr = coss * size.x;
|
||||||
*cast(float*)(ptr+4) = -sinn * size.y;
|
*cast(float*)(ptr+4) = -sinn * size.y;
|
||||||
*cast(float*)(ptr+8) = sinn * size.x;
|
*cast(float*)(ptr+8) = sinn * size.x;
|
||||||
|
|
@ -477,12 +510,12 @@ struct Renderer
|
||||||
|
|
||||||
//memcpy(ptr,);
|
//memcpy(ptr,);
|
||||||
memcpy(ptr+16,pos.data.ptr,8);
|
memcpy(ptr+16,pos.data.ptr,8);
|
||||||
memcpy(ptr+32,coords.data.ptr,16);
|
memcpy(ptr+32,data.coords.data.ptr,16);
|
||||||
|
|
||||||
//render_list[item_id] = RenderData(tex,material_id,mesh_id);
|
//render_list[item_id] = RenderData(tex,material_id,mesh_id);
|
||||||
render_list[item_id].texture = tex;
|
render_list[item_id].texture = *cast(Texture*)&data.texture;
|
||||||
render_list[item_id].material_id = material_id;
|
render_list[item_id].material_id = data.material_id;
|
||||||
render_list[item_id].mesh_id = mesh_id;
|
render_list[item_id].mesh_id = data.mesh_id;
|
||||||
|
|
||||||
data_index += data_offset;
|
data_index += data_offset;
|
||||||
item_id++;
|
item_id++;
|
||||||
|
|
@ -490,18 +523,43 @@ struct Renderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0)
|
// private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0)
|
||||||
|
private static void __draw_gl_vbo_batch(ref Renderer this_, scope ref const(DrawData) data)
|
||||||
{
|
{
|
||||||
import ecs_utils.gfx.config;
|
import ecs_utils.gfx.config;
|
||||||
short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)];
|
|
||||||
//import core.stdc.string;
|
//import core.stdc.string;
|
||||||
with(this_)
|
with(this_)
|
||||||
{
|
{
|
||||||
|
uint thread_id = data.thread_id;
|
||||||
//if(item_id >= MaxObjects)return;
|
//if(item_id >= MaxObjects)return;
|
||||||
//pos += view_pos;
|
//pos += view_pos;
|
||||||
|
Thread* thread = &threads[thread_id];
|
||||||
|
VertexBlock* block;
|
||||||
|
assert(thread.blocks.length > data.material_id);
|
||||||
|
block = &thread.blocks[data.material_id];
|
||||||
|
if(block.items == 0)
|
||||||
|
{
|
||||||
|
thread.blocks[data.material_id] = getBlock();
|
||||||
|
block = &thread.blocks[data.material_id];
|
||||||
|
block.material_id = data.material_id;
|
||||||
|
}
|
||||||
|
else if(block.items >= VertexBlock.max_items)
|
||||||
|
{
|
||||||
|
//pushBlock(thread.block);
|
||||||
|
prepared_items += block.items;
|
||||||
|
thread.filled_blocks.add(*block);
|
||||||
|
thread.blocks[data.material_id] = getBlock();
|
||||||
|
block = &thread.blocks[data.material_id];
|
||||||
|
block.material_id = data.material_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
short[3] mem = [data.depth, *cast(short*)&data.color, *(cast(short*)&data.color + 1)];
|
||||||
|
|
||||||
pos.x = pos.x * view_size.x + view_pos.x;
|
vec2 pos = void;
|
||||||
pos.y = pos.y * view_size.y + view_pos.y;//*/
|
vec2 size = void;
|
||||||
|
pos.x = data.position.x * view_size.x + view_pos.x;
|
||||||
|
pos.y = data.position.y * view_size.y + view_pos.y;//*/
|
||||||
|
|
||||||
/*void* ptr = data_ptr + data_index;
|
/*void* ptr = data_ptr + data_index;
|
||||||
*cast(float*)ptr = size.x;
|
*cast(float*)ptr = size.x;
|
||||||
|
|
@ -512,13 +570,16 @@ struct Renderer
|
||||||
memcpy(ptr+16,pos.data.ptr,8);
|
memcpy(ptr+16,pos.data.ptr,8);
|
||||||
memcpy(ptr+32,coords.data.ptr,16);*/
|
memcpy(ptr+32,coords.data.ptr,16);*/
|
||||||
|
|
||||||
short[] verts = cast(short[])threads[thread_id].block.batch_vertices;
|
short[] verts = (cast(short*)block.batch_vertices.ptr)[0..block.batch_vertices.length>>1];
|
||||||
uint item_id = threads[thread_id].block.items;
|
uint item_id = block.items;
|
||||||
|
|
||||||
if(angle == 0)
|
uint mesh_id = data.mesh_id;
|
||||||
|
vec4 coords = data.coords;
|
||||||
|
|
||||||
|
if(data.angle == 0)
|
||||||
{
|
{
|
||||||
size.x *= view_size.x;
|
size.x = data.size.x * view_size.x;
|
||||||
size.y *= view_size.y;
|
size.y = data.size.y * view_size.y;
|
||||||
|
|
||||||
verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191);
|
verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191);
|
||||||
verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191);
|
verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191);
|
||||||
|
|
@ -550,10 +611,11 @@ struct Renderer
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//import core.stdc.math;
|
//import core.stdc.math;
|
||||||
float sinx = sinf(angle) * size.x * view_size.y;
|
float angle = data.angle;
|
||||||
float cosx = cosf(angle) * size.x * view_size.x;
|
float sinx = sinf(angle) * data.size.x * view_size.y;
|
||||||
float siny = sinf(angle) * size.y * view_size.x;
|
float cosx = cosf(angle) * data.size.x * view_size.x;
|
||||||
float cosy = cosf(angle) * size.y * view_size.y;
|
float siny = sinf(angle) * data.size.y * view_size.x;
|
||||||
|
float cosy = cosf(angle) * data.size.y * view_size.y;
|
||||||
|
|
||||||
/*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x;
|
/*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x;
|
||||||
batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y;
|
batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y;
|
||||||
|
|
@ -618,7 +680,7 @@ struct Renderer
|
||||||
|
|
||||||
uint ind_id = (item_id % batch_size)*4;
|
uint ind_id = (item_id % batch_size)*4;
|
||||||
|
|
||||||
ushort[] indices = threads[thread_id].block.batch_indices;
|
ushort[] indices = block.batch_indices;
|
||||||
|
|
||||||
indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id);
|
indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id);
|
||||||
indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id);
|
indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id);
|
||||||
|
|
@ -633,13 +695,7 @@ struct Renderer
|
||||||
//render_list[item_id].mesh_id = mesh_id;
|
//render_list[item_id].mesh_id = mesh_id;
|
||||||
|
|
||||||
//data_index += 1;//data_offset;
|
//data_index += 1;//data_offset;
|
||||||
threads[thread_id].block.items++;
|
block.items++;
|
||||||
if(threads[thread_id].block.items >= VertexBlock.max_items)
|
|
||||||
{
|
|
||||||
//pushBlock(threads[thread_id].block);
|
|
||||||
threads[thread_id].blocks.add(threads[thread_id].block);
|
|
||||||
threads[thread_id].block = getBlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,6 +713,7 @@ struct Renderer
|
||||||
{
|
{
|
||||||
glClearColor(0,0,0,0);
|
glClearColor(0,0,0,0);
|
||||||
glViewport(0,0,this_.resolution.x,this_.resolution.y);
|
glViewport(0,0,this_.resolution.x,this_.resolution.y);
|
||||||
|
glDepthMask(1);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
//glDisable(GL_DEPTH_TEST);
|
//glDisable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
@ -667,6 +724,10 @@ struct Renderer
|
||||||
{
|
{
|
||||||
glDepthRangef(0,1);
|
glDepthRangef(0,1);
|
||||||
}
|
}
|
||||||
|
else version(Android)
|
||||||
|
{
|
||||||
|
glDepthRangef(0,1);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDepthRange(0,1);
|
glDepthRange(0,1);
|
||||||
|
|
@ -822,9 +883,9 @@ struct Renderer
|
||||||
//uint items = item_id/batch_size+1;
|
//uint items = item_id/batch_size+1;
|
||||||
foreach(i; 0..draw_list.length)
|
foreach(i; 0..draw_list.length)
|
||||||
{
|
{
|
||||||
if(material_id != render_list[i].material_id)
|
if(material_id != draw_list[i].material_id)
|
||||||
{
|
{
|
||||||
material_id = render_list[i].material_id;
|
material_id = draw_list[i].material_id;
|
||||||
GfxConfig.materials[material_id].bind();
|
GfxConfig.materials[material_id].bind();
|
||||||
float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1];
|
float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1];
|
||||||
GfxConfig.materials[material_id].pushUniforms(data.ptr);
|
GfxConfig.materials[material_id].pushUniforms(data.ptr);
|
||||||
|
|
@ -1054,7 +1115,8 @@ struct Renderer
|
||||||
view_pos = (pos - size * 0.5) * view_size;
|
view_pos = (pos - size * 0.5) * view_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw;
|
// __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw;
|
||||||
|
__gshared void function(ref Renderer this_, scope ref const(DrawData) data) __draw;
|
||||||
__gshared void function(ref Renderer this_) __present;
|
__gshared void function(ref Renderer this_) __present;
|
||||||
__gshared void function(ref Renderer this_) __clear;
|
__gshared void function(ref Renderer this_) __clear;
|
||||||
__gshared void function(ref Renderer this_) __initialize;
|
__gshared void function(ref Renderer this_) __initialize;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import bindbc.sdl;
|
||||||
|
|
||||||
import bubel.ecs.std;
|
import bubel.ecs.std;
|
||||||
|
|
||||||
import glad.gl.gl;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
//version = ver1;
|
//version = ver1;
|
||||||
|
|
||||||
|
|
@ -67,10 +69,12 @@ struct Shader
|
||||||
}
|
}
|
||||||
|
|
||||||
version(WebAssembly)const char* glsl = "#version 100\n";
|
version(WebAssembly)const char* glsl = "#version 100\n";
|
||||||
|
else version(Android)const char* glsl = "#version 100\n";
|
||||||
else const char* glsl = "#version 330\n";
|
else const char* glsl = "#version 330\n";
|
||||||
const char* buffer = data.code.ptr;
|
const char* buffer = data.code.ptr;
|
||||||
char* ver;
|
char* ver;
|
||||||
version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr;
|
version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr;
|
||||||
|
else version(Android)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr;
|
||||||
else ver = cast(char*)"#define ver1 1\n".ptr;
|
else ver = cast(char*)"#define ver1 1\n".ptr;
|
||||||
/*switch(__ecs_used_technique)
|
/*switch(__ecs_used_technique)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
||||||
|
|
||||||
import ecs_utils.math.vector;
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
import glad.gl.gl;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
|
|
@ -53,6 +55,7 @@ struct Texture
|
||||||
data.bpp = surf.format.BytesPerPixel;
|
data.bpp = surf.format.BytesPerPixel;
|
||||||
data.data = Mallocator.makeArray!ubyte(surf.w*surf.h*surf.format.BytesPerPixel);
|
data.data = Mallocator.makeArray!ubyte(surf.w*surf.h*surf.format.BytesPerPixel);
|
||||||
data.data[0..$] = (cast(ubyte*)surf.pixels)[0..data.data.length];
|
data.data[0..$] = (cast(ubyte*)surf.pixels)[0..data.data.length];
|
||||||
|
data.size = ivec2(surf.w, surf.h);
|
||||||
|
|
||||||
SDL_FreeSurface(surf);
|
SDL_FreeSurface(surf);
|
||||||
|
|
||||||
|
|
@ -65,8 +68,8 @@ struct Texture
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
if(data.bpp == 3)glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,surf.w,surf.h,0,GL_RGB,GL_UNSIGNED_BYTE,data.data.ptr);
|
if(data.bpp == 3)glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,data.size.x,data.size.y,0,GL_RGB,GL_UNSIGNED_BYTE,data.data.ptr);
|
||||||
else if(data.bpp == 4)glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,surf.w,surf.h,0,GL_RGBA,GL_UNSIGNED_BYTE,data.data.ptr);
|
else if(data.bpp == 4)glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,data.size.x,data.size.y,0,GL_RGBA,GL_UNSIGNED_BYTE,data.data.ptr);
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +83,7 @@ struct Texture
|
||||||
glBindTexture(GL_TEXTURE_2D, data.gl_handle);
|
glBindTexture(GL_TEXTURE_2D, data.gl_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void destory() @nogc nothrow
|
void destroy() @nogc nothrow
|
||||||
{
|
{
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,9 @@ else :
|
||||||
|
|
||||||
import bindbc.sdl;
|
import bindbc.sdl;
|
||||||
|
|
||||||
import glad.gl.gl;
|
version(WebAssembly)import glad.gl.gles2;
|
||||||
|
else version(Android)import glad.gl.gles2;
|
||||||
|
else import glad.gl.gl;
|
||||||
|
|
||||||
import cimgui.cimgui;
|
import cimgui.cimgui;
|
||||||
|
|
||||||
|
|
@ -210,7 +212,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons()
|
||||||
|
|
||||||
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor.
|
// SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor.
|
||||||
// The function is only supported from SDL 2.0.4 (released Jan 2016)
|
// The function is only supported from SDL 2.0.4 (released Jan 2016)
|
||||||
bool any_mouse_button_down = ImGui::IsAnyMouseDown();
|
bool any_mouse_button_down = ImGui.IsAnyMouseDown();
|
||||||
SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE);
|
SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE);
|
||||||
//#else*/
|
//#else*/
|
||||||
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
|
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
|
||||||
|
|
@ -291,10 +293,11 @@ void ImGuiImplSDL2NewFrame(SDL_Window* window)
|
||||||
int w, h;
|
int w, h;
|
||||||
int display_w, display_h;
|
int display_w, display_h;
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
|
// SDL_GL_GetDrawableSize(window, &display_w, &display_h); FIXME: you see
|
||||||
io.DisplaySize = ImVec2(cast(float)w, cast(float)h);
|
io.DisplaySize = ImVec2(cast(float)w, cast(float)h);
|
||||||
if (w > 0 && h > 0)
|
// if (w > 0 && h > 0)
|
||||||
io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h);
|
// io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h);
|
||||||
|
io.DisplayFramebufferScale = ImVec2(1,1);
|
||||||
|
|
||||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||||
frequency = SDL_GetPerformanceFrequency();
|
frequency = SDL_GetPerformanceFrequency();
|
||||||
|
|
@ -310,89 +313,460 @@ void ImGuiImplSDL2NewFrame(SDL_Window* window)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__gshared GLuint g_GlVersion = 0; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
|
||||||
|
__gshared char[32] g_GlslVersionString = ""; // Specified by user or detected based on compile time GL settings.
|
||||||
|
//__gshared GLuint g_FontTexture = 0;
|
||||||
|
__gshared GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
|
||||||
|
__gshared int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location
|
||||||
|
__gshared int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location
|
||||||
|
__gshared uint g_VboHandle = 0, g_ElementsHandle = 0;
|
||||||
|
|
||||||
|
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ImGuiImplOpenGL2Init()
|
|
||||||
{
|
{
|
||||||
// Setup back-end capabilities flags
|
// Setup back-end capabilities flags
|
||||||
ImGuiIO* io = igGetIO();
|
ImGuiIO* io = igGetIO();
|
||||||
io.BackendRendererName = "imgui_impl_opengl2";
|
io.BackendRendererName = "imgui_impl_opengl3";
|
||||||
|
|
||||||
|
|
||||||
|
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
||||||
|
// Note: GLSL version is NOT the same as GL version. Leave this to null if unsure.
|
||||||
|
/*#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||||
|
if (glsl_version == null)
|
||||||
|
glsl_version = "#version 100";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_ES3)
|
||||||
|
if (glsl_version == null)
|
||||||
|
glsl_version = "#version 300 es";
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
if (glsl_version == null)
|
||||||
|
glsl_version = "#version 150";
|
||||||
|
#else
|
||||||
|
if (glsl_version == null)
|
||||||
|
glsl_version = "#version 130";
|
||||||
|
#endif
|
||||||
|
IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));*/
|
||||||
|
//const (char)*glsl_version = "#version 100";
|
||||||
|
import core.stdc.string;
|
||||||
|
strcpy(g_GlslVersionString.ptr, glsl_version);
|
||||||
|
strcat(g_GlslVersionString.ptr, "\n");
|
||||||
|
|
||||||
|
// Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected.
|
||||||
|
// The code actually never uses the 'gl_loader' variable! It is only here so you can read it!
|
||||||
|
// If auto-detection fails or doesn't select the same GL loader file as used by your application,
|
||||||
|
// you are likely to get a crash below.
|
||||||
|
// You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
||||||
|
/*const char* gl_loader = "Unknown";
|
||||||
|
IM_UNUSED(gl_loader);
|
||||||
|
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
|
||||||
|
gl_loader = "GL3W";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
|
||||||
|
gl_loader = "GLEW";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
|
||||||
|
gl_loader = "GLAD";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
|
||||||
|
gl_loader = "glbinding2";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
|
||||||
|
gl_loader = "glbinding3";
|
||||||
|
#elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
|
||||||
|
gl_loader = "custom";
|
||||||
|
#else
|
||||||
|
gl_loader = "none";
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
// Make a dummy GL call (we don't actually need the result)
|
||||||
|
// IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
|
||||||
|
// Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
|
||||||
|
/*GLint current_texture;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiImplOpenGL2Shutdown()
|
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||||
{
|
{
|
||||||
ImGuiImplOpenGL2DestroyDeviceObjects();
|
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiImplOpenGL2NewFrame()
|
|
||||||
{
|
|
||||||
if (!g_FontTexture)
|
|
||||||
ImGuiImplOpenGL2CreateDeviceObjects();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGuiImplOpenGL2SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
|
||||||
{
|
|
||||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
//glDisable(GL_LIGHTING);
|
|
||||||
//glDisable(GL_COLOR_MATERIAL);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
// #ifdef GL_POLYGON_MODE
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
// #endif
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
|
|
||||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||||
// you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function:
|
bool clip_origin_lower_left = true;
|
||||||
// GLint last_program;
|
// #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
|
||||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
// GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
||||||
// glUseProgram(0);
|
// if (current_clip_origin == GL_UPPER_LEFT)
|
||||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
// clip_origin_lower_left = false;
|
||||||
// glUseProgram(last_program)
|
// #endif
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
// Setup viewport, orthographic projection matrix
|
||||||
// Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
// Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||||
glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height);
|
glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height);
|
||||||
glMatrixMode(GL_PROJECTION);
|
float L = draw_data.DisplayPos.x;
|
||||||
glPushMatrix();
|
float R = draw_data.DisplayPos.x + draw_data.DisplaySize.x;
|
||||||
glLoadIdentity();
|
float T = draw_data.DisplayPos.y;
|
||||||
glOrtho(draw_data.DisplayPos.x, draw_data.DisplayPos.x + draw_data.DisplaySize.x, draw_data.DisplayPos.y + draw_data.DisplaySize.y, draw_data.DisplayPos.y, -1.0f, +1.0f);
|
float B = draw_data.DisplayPos.y + draw_data.DisplaySize.y;
|
||||||
glMatrixMode(GL_MODELVIEW);
|
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
||||||
glPushMatrix();
|
const float[4][4] ortho_projection =
|
||||||
glLoadIdentity();
|
[
|
||||||
|
[ 2.0f/(R-L), 0.0f, 0.0f, 0.0f ],
|
||||||
|
[ 0.0f, 2.0f/(T-B), 0.0f, 0.0f ],
|
||||||
|
[ 0.0f, 0.0f, -1.0f, 0.0f ],
|
||||||
|
[ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f ],
|
||||||
|
];
|
||||||
|
glUseProgram(g_ShaderHandle);
|
||||||
|
glUniform1i(g_AttribLocationTex, 0);
|
||||||
|
glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||||
|
// #ifdef GL_SAMPLER_BINDING
|
||||||
|
// glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// (void)vertex_array_object;
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// glBindVertexArray(vertex_array_object);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// Bind vertex/index buffers and setup attributes for ImDrawVert
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationVtxPos);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationVtxUV);
|
||||||
|
glEnableVertexAttribArray(g_AttribLocationVtxColor);
|
||||||
|
glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.pos.offsetof);
|
||||||
|
glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.uv.offsetof);
|
||||||
|
glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.col.offsetof);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL2 Render function.
|
|
||||||
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
void ImGui_ImplOpenGL3_Shutdown()
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
|
{
|
||||||
void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data)
|
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplOpenGL3_NewFrame()
|
||||||
|
{
|
||||||
|
if (!g_ShaderHandle)
|
||||||
|
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
// Backup GL state
|
||||||
|
GLint last_texture, last_array_buffer;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// GLint last_vertex_array;
|
||||||
|
// glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// Parse GLSL version string
|
||||||
|
import core.stdc.stdio;
|
||||||
|
int glsl_version = 130;
|
||||||
|
sscanf(g_GlslVersionString.ptr, "#version %d", &glsl_version);
|
||||||
|
|
||||||
|
const GLchar* vertex_shader_glsl_120 =
|
||||||
|
"uniform mat4 ProjMtx;\n
|
||||||
|
attribute vec2 Position;\n
|
||||||
|
attribute vec2 UV;\n
|
||||||
|
attribute vec4 Color;\n
|
||||||
|
varying vec2 Frag_UV;\n
|
||||||
|
varying vec4 Frag_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Frag_UV = UV;\n
|
||||||
|
Frag_Color = Color;\n
|
||||||
|
gl_Position = ProjMtx * vec4(Position.xy,0,1);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* vertex_shader_glsl_130 =
|
||||||
|
"uniform mat4 ProjMtx;\n
|
||||||
|
in vec2 Position;\n
|
||||||
|
in vec2 UV;\n
|
||||||
|
in vec4 Color;\n
|
||||||
|
out vec2 Frag_UV;\n
|
||||||
|
out vec4 Frag_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Frag_UV = UV;\n
|
||||||
|
Frag_Color = Color;\n
|
||||||
|
gl_Position = ProjMtx * vec4(Position.xy,0,1);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* vertex_shader_glsl_300_es =
|
||||||
|
"precision mediump float;\n
|
||||||
|
layout (location = 0) in vec2 Position;\n
|
||||||
|
layout (location = 1) in vec2 UV;\n
|
||||||
|
layout (location = 2) in vec4 Color;\n
|
||||||
|
uniform mat4 ProjMtx;\n
|
||||||
|
out vec2 Frag_UV;\n
|
||||||
|
out vec4 Frag_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Frag_UV = UV;\n
|
||||||
|
Frag_Color = Color;\n
|
||||||
|
gl_Position = ProjMtx * vec4(Position.xy,0,1);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* vertex_shader_glsl_410_core =
|
||||||
|
"layout (location = 0) in vec2 Position;\n
|
||||||
|
layout (location = 1) in vec2 UV;\n
|
||||||
|
layout (location = 2) in vec4 Color;\n
|
||||||
|
uniform mat4 ProjMtx;\n
|
||||||
|
out vec2 Frag_UV;\n
|
||||||
|
out vec4 Frag_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Frag_UV = UV;\n
|
||||||
|
Frag_Color = Color;\n
|
||||||
|
gl_Position = ProjMtx * vec4(Position.xy,0,1);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* fragment_shader_glsl_120 =
|
||||||
|
"#ifdef GL_ES\n
|
||||||
|
precision mediump float;\n
|
||||||
|
#endif\n
|
||||||
|
uniform sampler2D Texture;\n
|
||||||
|
varying vec2 Frag_UV;\n
|
||||||
|
varying vec4 Frag_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* fragment_shader_glsl_130 =
|
||||||
|
"uniform sampler2D Texture;\n
|
||||||
|
in vec2 Frag_UV;\n
|
||||||
|
in vec4 Frag_Color;\n
|
||||||
|
out vec4 Out_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* fragment_shader_glsl_300_es =
|
||||||
|
"precision mediump float;\n
|
||||||
|
uniform sampler2D Texture;\n
|
||||||
|
in vec2 Frag_UV;\n
|
||||||
|
in vec4 Frag_Color;\n
|
||||||
|
layout (location = 0) out vec4 Out_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
const GLchar* fragment_shader_glsl_410_core =
|
||||||
|
"in vec2 Frag_UV;\n
|
||||||
|
in vec4 Frag_Color;\n
|
||||||
|
uniform sampler2D Texture;\n
|
||||||
|
layout (location = 0) out vec4 Out_Color;\n
|
||||||
|
void main()\n
|
||||||
|
{\n
|
||||||
|
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
// Select shaders matching our GLSL versions
|
||||||
|
const (char)* vertex_shader = null;
|
||||||
|
const (char)* fragment_shader = null;
|
||||||
|
if (glsl_version < 130)
|
||||||
|
{
|
||||||
|
vertex_shader = vertex_shader_glsl_120;
|
||||||
|
fragment_shader = fragment_shader_glsl_120;
|
||||||
|
}
|
||||||
|
else if (glsl_version >= 410)
|
||||||
|
{
|
||||||
|
vertex_shader = vertex_shader_glsl_410_core;
|
||||||
|
fragment_shader = fragment_shader_glsl_410_core;
|
||||||
|
}
|
||||||
|
else if (glsl_version == 300)
|
||||||
|
{
|
||||||
|
vertex_shader = vertex_shader_glsl_300_es;
|
||||||
|
fragment_shader = fragment_shader_glsl_300_es;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertex_shader = vertex_shader_glsl_130;
|
||||||
|
fragment_shader = fragment_shader_glsl_130;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create shaders
|
||||||
|
const (char)*[2] vertex_shader_with_version = [ g_GlslVersionString.ptr, vertex_shader ];
|
||||||
|
g_VertHandle = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(g_VertHandle, 2, vertex_shader_with_version.ptr, null);
|
||||||
|
glCompileShader(g_VertHandle);
|
||||||
|
CheckShader(g_VertHandle, "vertex shader");
|
||||||
|
|
||||||
|
const (char)*[2] fragment_shader_with_version = [ g_GlslVersionString.ptr, fragment_shader ];
|
||||||
|
g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(g_FragHandle, 2, fragment_shader_with_version.ptr, null);
|
||||||
|
glCompileShader(g_FragHandle);
|
||||||
|
CheckShader(g_FragHandle, "fragment shader");
|
||||||
|
|
||||||
|
g_ShaderHandle = glCreateProgram();
|
||||||
|
glAttachShader(g_ShaderHandle, g_VertHandle);
|
||||||
|
glAttachShader(g_ShaderHandle, g_FragHandle);
|
||||||
|
glLinkProgram(g_ShaderHandle);
|
||||||
|
CheckProgram(g_ShaderHandle, "shader program");
|
||||||
|
|
||||||
|
g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture");
|
||||||
|
g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx");
|
||||||
|
g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position");
|
||||||
|
g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV");
|
||||||
|
g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color");
|
||||||
|
|
||||||
|
// Create buffers
|
||||||
|
glGenBuffers(1, &g_VboHandle);
|
||||||
|
glGenBuffers(1, &g_ElementsHandle);
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||||
|
|
||||||
|
// Restore modified GL state
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// glBindVertexArray(last_vertex_array);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
||||||
|
{
|
||||||
|
if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; }
|
||||||
|
if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; }
|
||||||
|
if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); }
|
||||||
|
if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); }
|
||||||
|
if (g_VertHandle) { glDeleteShader(g_VertHandle); g_VertHandle = 0; }
|
||||||
|
if (g_FragHandle) { glDeleteShader(g_FragHandle); g_FragHandle = 0; }
|
||||||
|
if (g_ShaderHandle) { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; }
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckShader(GLuint handle, const char* desc)
|
||||||
|
{
|
||||||
|
GLint status = 0, log_length = 0;
|
||||||
|
glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
||||||
|
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
|
/*if (cast(GLboolean)status == GL_FALSE)
|
||||||
|
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc);
|
||||||
|
if (log_length > 1)
|
||||||
|
{
|
||||||
|
ImVector<char> buf;
|
||||||
|
buf.resize(cast(int)(log_length + 1));
|
||||||
|
glGetShaderInfoLog(handle, log_length, null, cast(GLchar*)buf.begin());
|
||||||
|
fprintf(stderr, "%s\n", buf.begin());
|
||||||
|
}*/
|
||||||
|
return cast(GLboolean)status == GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If you get an error please report on GitHub. You may try different GL context version or GLSL version.
|
||||||
|
static bool CheckProgram(GLuint handle, const char* desc)
|
||||||
|
{
|
||||||
|
GLint status = 0, log_length = 0;
|
||||||
|
glGetProgramiv(handle, GL_LINK_STATUS, &status);
|
||||||
|
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length);
|
||||||
|
/*if (cast(GLboolean)status == GL_FALSE)
|
||||||
|
fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString);
|
||||||
|
if (log_length > 1)
|
||||||
|
{
|
||||||
|
ImVector<char> buf;
|
||||||
|
buf.resize(cast(int)(log_length + 1));
|
||||||
|
glGetProgramInfoLog(handle, log_length, null, cast(GLchar*)buf.begin());
|
||||||
|
fprintf(stderr, "%s\n", buf.begin());
|
||||||
|
}*/
|
||||||
|
return cast(GLboolean)status == GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO* io = igGetIO();
|
||||||
|
ubyte* pixels;
|
||||||
|
int width, height, bpp;
|
||||||
|
|
||||||
|
ImFontAtlas_GetTexDataAsRGBA32(io.Fonts,&pixels, &width, &height, &bpp);
|
||||||
|
//io.Fonts.GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||||
|
|
||||||
|
// Upload texture to graphics system
|
||||||
|
GLint last_texture;
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
|
glGenTextures(1, &g_FontTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// #ifdef GL_UNPACK_ROW_LENGTH
|
||||||
|
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
// #endif
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
|
// Store our identifier
|
||||||
|
io.Fonts.TexID = cast(ImTextureID)cast(sizediff_t)g_FontTexture;
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplOpenGL3_DestroyFontsTexture()
|
||||||
|
{
|
||||||
|
if (g_FontTexture)
|
||||||
|
{
|
||||||
|
ImGuiIO* io = igGetIO();
|
||||||
|
glDeleteTextures(1, &g_FontTexture);
|
||||||
|
io.Fonts.TexID = null;
|
||||||
|
g_FontTexture = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
int fb_width = cast(int)(draw_data.DisplaySize.x * draw_data.FramebufferScale.x);
|
int fb_width = cast(int)(draw_data.DisplaySize.x * draw_data.FramebufferScale.x);
|
||||||
int fb_height = cast(int)(draw_data.DisplaySize.y * draw_data.FramebufferScale.y);
|
int fb_height = cast(int)(draw_data.DisplaySize.y * draw_data.FramebufferScale.y);
|
||||||
if (fb_width == 0 || fb_height == 0)
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Backup GL state
|
// Backup GL state
|
||||||
|
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, cast(GLint*)&last_active_texture);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||||
GLint[2] last_polygon_mode; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode.ptr);
|
// #ifdef GL_SAMPLER_BINDING
|
||||||
|
// GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
|
||||||
|
// #endif
|
||||||
|
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object);
|
||||||
|
// #endif
|
||||||
|
// #ifdef GL_POLYGON_MODE
|
||||||
|
// GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||||
|
// #endif
|
||||||
GLint[4] last_viewport; glGetIntegerv(GL_VIEWPORT, last_viewport.ptr);
|
GLint[4] last_viewport; glGetIntegerv(GL_VIEWPORT, last_viewport.ptr);
|
||||||
GLint[4] last_scissor_box; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr);
|
GLint[4] last_scissor_box; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr);
|
||||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, cast(GLint*)&last_blend_src_rgb);
|
||||||
|
GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, cast(GLint*)&last_blend_dst_rgb);
|
||||||
|
GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, cast(GLint*)&last_blend_src_alpha);
|
||||||
|
GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, cast(GLint*)&last_blend_dst_alpha);
|
||||||
|
GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, cast(GLint*)&last_blend_equation_rgb);
|
||||||
|
GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, cast(GLint*)&last_blend_equation_alpha);
|
||||||
|
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
|
||||||
|
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
|
||||||
|
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
// Setup desired GL state
|
// Setup desired GL state
|
||||||
ImGuiImplOpenGL2SetupRenderState(draw_data, fb_width, fb_height);
|
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
|
||||||
|
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
|
||||||
|
GLuint vertex_array_object = 0;
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// glGenVertexArrays(1, &vertex_array_object);
|
||||||
|
// #endif
|
||||||
|
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_off = draw_data.DisplayPos; // (0,0) unless using multi-viewports
|
ImVec2 clip_off = draw_data.DisplayPos; // (0,0) unless using multi-viewports
|
||||||
|
|
@ -401,23 +775,22 @@ void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data)
|
||||||
// Render command lists
|
// Render command lists
|
||||||
for (int n = 0; n < draw_data.CmdListsCount; n++)
|
for (int n = 0; n < draw_data.CmdListsCount; n++)
|
||||||
{
|
{
|
||||||
ImDrawList* cmd_list = draw_data.CmdLists[n];
|
const ImDrawList* cmd_list = draw_data.CmdLists[n];
|
||||||
ImDrawVert* vtx_buffer = cmd_list.VtxBuffer.Data;
|
|
||||||
ImDrawIdx* idx_buffer = cmd_list.IdxBuffer.Data;
|
// Upload vertex/index buffers
|
||||||
glVertexPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.pos.offsetof));
|
glBufferData(GL_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.VtxBuffer.Size * ImDrawVert.sizeof, cast(const GLvoid*)cmd_list.VtxBuffer.Data, GL_STREAM_DRAW);
|
||||||
glTexCoordPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.uv.offsetof));
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.IdxBuffer.Size * ImDrawIdx.sizeof, cast(const GLvoid*)cmd_list.IdxBuffer.Data, GL_STREAM_DRAW);
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.col.offsetof));
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
|
for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
|
||||||
{
|
{
|
||||||
const ImDrawCmd* pcmd = &cmd_list.CmdBuffer.Data[cmd_i];
|
const ImDrawCmd* pcmd = &cmd_list.CmdBuffer.Data[cmd_i];
|
||||||
if (pcmd.UserCallback)
|
if (pcmd.UserCallback != null)
|
||||||
{
|
{
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
/*if (pcmd.UserCallback == &ImDrawCallback_ResetRenderState)
|
// if (pcmd.UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
// ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||||
else*/
|
// else
|
||||||
pcmd.UserCallback(cmd_list, pcmd);
|
pcmd.UserCallback(cmd_list, pcmd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -435,74 +808,43 @@ void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data)
|
||||||
glScissor(cast(int)clip_rect.x, cast(int)(fb_height - clip_rect.w), cast(int)(clip_rect.z - clip_rect.x), cast(int)(clip_rect.w - clip_rect.y));
|
glScissor(cast(int)clip_rect.x, cast(int)(fb_height - clip_rect.w), cast(int)(clip_rect.z - clip_rect.x), cast(int)(clip_rect.w - clip_rect.y));
|
||||||
|
|
||||||
// Bind texture, Draw
|
// Bind texture, Draw
|
||||||
glBindTexture(GL_TEXTURE_2D, cast(GLuint)pcmd.TextureId);
|
glBindTexture(GL_TEXTURE_2D, cast(GLuint)cast(sizediff_t)pcmd.TextureId);
|
||||||
glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
// #if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||||
|
// if (g_GlVersion >= 320)
|
||||||
|
// glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd.ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd.IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd.VtxOffset);
|
||||||
|
// else
|
||||||
|
// #endif
|
||||||
|
glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, cast(void*)cast(sizediff_t)(pcmd.IdxOffset * ImDrawIdx.sizeof));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
idx_buffer += pcmd.ElemCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destroy the temporary VAO
|
||||||
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
|
// glDeleteVertexArrays(1, &vertex_array_object);
|
||||||
|
// #endif
|
||||||
|
|
||||||
// Restore modified GL state
|
// Restore modified GL state
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glUseProgram(last_program);
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
// #ifdef GL_SAMPLER_BINDING
|
||||||
glBindTexture(GL_TEXTURE_2D, cast(GLuint)last_texture);
|
// glBindSampler(0, last_sampler);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
// #endif
|
||||||
glPopMatrix();
|
glActiveTexture(last_active_texture);
|
||||||
glMatrixMode(GL_PROJECTION);
|
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
glPopMatrix();
|
// glBindVertexArray(last_vertex_array_object);
|
||||||
glPopAttrib();
|
// #endif
|
||||||
glPolygonMode(GL_FRONT, cast(GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, cast(GLenum)last_polygon_mode[1]);
|
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||||
|
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
|
||||||
|
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
|
||||||
|
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
|
||||||
|
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
|
||||||
|
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
|
||||||
|
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
|
||||||
|
// #ifdef GL_POLYGON_MODE
|
||||||
|
// glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
||||||
|
// #endif
|
||||||
glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]);
|
glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]);
|
||||||
glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]);
|
glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]);
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGuiImplOpenGL2CreateFontsTexture()
|
|
||||||
{
|
|
||||||
// Build texture atlas
|
|
||||||
ImGuiIO* io = igGetIO();
|
|
||||||
ubyte* pixels;
|
|
||||||
int width, height;
|
|
||||||
int bpp;
|
|
||||||
ImFontAtlas_GetTexDataAsRGBA32(io.Fonts, &pixels, &width, &height, &bpp); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
GLint last_texture;
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
glGenTextures(1, &g_FontTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts.TexID = cast(ImTextureID)g_FontTexture;
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiImplOpenGL2DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
if (g_FontTexture)
|
|
||||||
{
|
|
||||||
ImGuiIO* io = igGetIO();
|
|
||||||
glDeleteTextures(1, &g_FontTexture);
|
|
||||||
io.Fonts.TexID = null;
|
|
||||||
g_FontTexture = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGuiImplOpenGL2CreateDeviceObjects()
|
|
||||||
{
|
|
||||||
return ImGuiImplOpenGL2CreateFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiImplOpenGL2DestroyDeviceObjects()
|
|
||||||
{
|
|
||||||
ImGuiImplOpenGL2DestroyFontsTexture();
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
module ecs_utils.math.vector;
|
module ecs_utils.math.vector;
|
||||||
|
|
||||||
|
import ecs_utils.utils;
|
||||||
|
|
||||||
struct vec2
|
struct vec2
|
||||||
{
|
{
|
||||||
this(float v) @nogc nothrow
|
this(float v) @nogc nothrow
|
||||||
|
|
@ -42,6 +44,11 @@ struct vec2
|
||||||
else static assert(0, "Operator "~op~" not implemented");
|
else static assert(0, "Operator "~op~" not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 opUnary(string op)()if (op == "-")
|
||||||
|
{
|
||||||
|
return vec2(-x,-y);
|
||||||
|
}
|
||||||
|
|
||||||
ivec2 opCast()
|
ivec2 opCast()
|
||||||
{
|
{
|
||||||
return ivec2(cast(int)x,cast(int)y);
|
return ivec2(cast(int)x,cast(int)y);
|
||||||
|
|
@ -71,6 +78,31 @@ struct vec2
|
||||||
}
|
}
|
||||||
else static assert(0, "Operator "~op~" not implemented");
|
else static assert(0, "Operator "~op~" not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float length2()
|
||||||
|
{
|
||||||
|
return x*x + y*y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float length()
|
||||||
|
{
|
||||||
|
return sqrtf(length2);
|
||||||
|
}
|
||||||
|
|
||||||
|
float fastSqrLength()
|
||||||
|
{
|
||||||
|
return rsqrt(length2);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 normalize()
|
||||||
|
{
|
||||||
|
return this * fastSqrLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float dot(vec2 a, vec2 b)
|
||||||
|
{
|
||||||
|
return a.x*b.x + a.y*b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vec4
|
struct vec4
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,26 @@ module ecs_utils.utils;
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
int randomRange(int min, int max)
|
import ecs_utils.math.vector;
|
||||||
|
|
||||||
|
enum PI = 3.141592653589793238462643383279502884197169399375105820;
|
||||||
|
|
||||||
|
extern(C) float sqrtf(float x) @nogc nothrow @system;
|
||||||
|
extern(C) float acosf(float x) @nogc nothrow @system;
|
||||||
|
extern(C) float sinf(float x) @nogc nothrow @system;
|
||||||
|
extern(C) float cosf(float x) @nogc nothrow @system;
|
||||||
|
extern(C) float powf(float x, float y) @nogc nothrow @system;
|
||||||
|
extern(C) float fabs(float x) @nogc nothrow @system;
|
||||||
|
extern(C) float log2f(float arg) @nogc nothrow @system;
|
||||||
|
|
||||||
|
|
||||||
|
int randomRange(int min, int max) nothrow @nogc @trusted
|
||||||
{
|
{
|
||||||
int range = max - min;
|
int range = max - min;
|
||||||
return rand() % range - min;
|
return rand() % range - min;
|
||||||
}
|
}
|
||||||
|
|
||||||
float randomf()
|
float randomf() nothrow @nogc @trusted
|
||||||
{
|
{
|
||||||
const float scale = 1.0 / 32_767.0;
|
const float scale = 1.0 / 32_767.0;
|
||||||
return cast(float)(rand() & 0x007FFF) * scale;
|
return cast(float)(rand() & 0x007FFF) * scale;
|
||||||
|
|
@ -21,6 +34,38 @@ float randomRangef(float min, float max)
|
||||||
return rand()%4096;
|
return rand()%4096;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
float mix(float x, float y, float a)
|
||||||
|
{
|
||||||
|
//return x*a + y*(a-1);
|
||||||
|
//return x*a + y*a - y;
|
||||||
|
return x*(a+y) - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rsqrt(float number)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
float x2, y;
|
||||||
|
const float threehalfs = 1.5F;
|
||||||
|
|
||||||
|
x2 = number * 0.5F;
|
||||||
|
y = number;
|
||||||
|
i = * cast( long * ) &y; // evil floating point bit level hacking
|
||||||
|
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
|
||||||
|
y = * cast( float * ) &i;
|
||||||
|
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 randomCircularSample() nothrow @nogc @trusted
|
||||||
|
{
|
||||||
|
float angle = 2 * PI * randomf;
|
||||||
|
float radius = sqrtf(randomf);
|
||||||
|
float s = sinf(angle);
|
||||||
|
float c = cosf(angle);
|
||||||
|
return vec2(c,s)*radius;
|
||||||
|
}
|
||||||
|
|
||||||
version(GNU)
|
version(GNU)
|
||||||
{
|
{
|
||||||
public import core.stdc.stdio : printf;
|
public import core.stdc.stdio : printf;
|
||||||
|
|
@ -32,9 +77,13 @@ version(GNU)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
extern(C) int printf(scope const char* format, ...) @nogc nothrow @system;
|
extern(C) int printf(scope const char* format, ...) @nogc nothrow @system;
|
||||||
public import std.array : staticArray;
|
// public import std.array : staticArray;
|
||||||
|
pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extern(C) int rand();
|
extern(C) int rand() nothrow @nogc @trusted;
|
||||||
|
|
||||||
version(D_BetterC)
|
version(D_BetterC)
|
||||||
{
|
{
|
||||||
|
|
@ -58,7 +107,15 @@ version(D_BetterC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version(Android)
|
||||||
|
{
|
||||||
|
alias pthread_key_t = uint;
|
||||||
|
|
||||||
|
extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow;
|
||||||
|
extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow;
|
||||||
|
extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow;
|
||||||
|
}
|
||||||
|
|
||||||
version(WebAssembly)
|
version(WebAssembly)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
6
dub.json
6
dub.json
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ecs",
|
"name": "bubel_ecs",
|
||||||
|
"targetName" : "ecs",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Michał Masiukiewicz", "Dawid Masiukiewicz"
|
"Michał Masiukiewicz", "Dawid Masiukiewicz"
|
||||||
],
|
],
|
||||||
|
|
@ -118,7 +119,8 @@
|
||||||
"-unittest"
|
"-unittest"
|
||||||
],
|
],
|
||||||
"dflags-gdc": [
|
"dflags-gdc": [
|
||||||
"-fno-druntime"
|
"-fno-druntime",
|
||||||
|
"-lpthread"
|
||||||
],
|
],
|
||||||
"sourcePaths": ["source/","tests/"],
|
"sourcePaths": ["source/","tests/"],
|
||||||
"mainSourceFile":"tests/runner.d",
|
"mainSourceFile":"tests/runner.d",
|
||||||
|
|
|
||||||
35
meson.build
35
meson.build
|
|
@ -23,6 +23,8 @@ tests_src = [
|
||||||
]
|
]
|
||||||
|
|
||||||
betterC_opt = get_option('betterC')
|
betterC_opt = get_option('betterC')
|
||||||
|
BuildDemos_opt = get_option('BuildDemos')
|
||||||
|
LTO_otp = get_option('LTO')
|
||||||
|
|
||||||
comp = meson.get_compiler('d')
|
comp = meson.get_compiler('d')
|
||||||
|
|
||||||
|
|
@ -31,16 +33,43 @@ comp_id = comp.get_id()
|
||||||
args = []
|
args = []
|
||||||
link_args = []
|
link_args = []
|
||||||
|
|
||||||
|
if comp_id == 'gcc'
|
||||||
|
args += '-pthread'
|
||||||
|
link_args += '-pthread'
|
||||||
|
endif
|
||||||
|
|
||||||
|
if LTO_otp
|
||||||
|
if comp_id == 'gcc'
|
||||||
|
args += '-flto'
|
||||||
|
link_args += '-flto'
|
||||||
|
elif comp_id == 'llvm'
|
||||||
|
args += '-flto=thin'
|
||||||
|
link_args += '-flto=thin'
|
||||||
|
else
|
||||||
|
message('LTO don\'t work with DMD')
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if betterC_opt
|
if betterC_opt
|
||||||
args += '-betterC'
|
if comp_id == 'gcc'
|
||||||
link_args += '-betterC'
|
args += ['-fno-druntime']
|
||||||
|
link_args += ['-fno-druntime']
|
||||||
|
else
|
||||||
|
args += '-betterC'
|
||||||
|
link_args += '-betterC'
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
inc = include_directories('source/')
|
inc = include_directories('source/')
|
||||||
tests_inc = include_directories('source/')
|
tests_inc = include_directories('source/')
|
||||||
|
|
||||||
ecs_lib = shared_library('ecs', src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args)
|
ecs_lib = library('ecs', src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args)
|
||||||
|
|
||||||
executable('tests', tests_src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args, link_with: ecs_lib)
|
executable('tests', tests_src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args, link_with: ecs_lib)
|
||||||
|
|
||||||
|
bubel_ecs_dep = declare_dependency(include_directories : [inc], link_with : ecs_lib)
|
||||||
|
|
||||||
|
if BuildDemos_opt
|
||||||
|
subdir('demos/utils')
|
||||||
|
subdir('demos')
|
||||||
|
endif
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
option('betterC', type: 'boolean', value: false)
|
option('betterC', type: 'boolean', value: false)
|
||||||
|
option('BuildDemos', type: 'boolean', value: false)
|
||||||
|
option('LTO', type: 'boolean', value: false)
|
||||||
|
|
@ -54,6 +54,7 @@ struct BlockAllocator
|
||||||
Mallocator.dispose(pointers);
|
Mallocator.dispose(pointers);
|
||||||
pointers = next_pointers;
|
pointers = next_pointers;
|
||||||
}
|
}
|
||||||
|
next_block = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,26 @@ struct Entity
|
||||||
*/
|
*/
|
||||||
T* getComponent(T)() const
|
T* getComponent(T)() const
|
||||||
{
|
{
|
||||||
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
/*EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof);
|
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof);*/
|
||||||
|
return cast(T*)getComponent(T.component_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasComponent(ushort component_id)
|
void* getComponent(ushort component_id) const
|
||||||
|
{
|
||||||
|
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
||||||
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (cast(void*)block + info.deltas[component_id] + block.entityIndex(&this) * gEM.components[component_id].size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasComponent(ushort component_id) const
|
||||||
{
|
{
|
||||||
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
|
|
@ -50,7 +61,7 @@ struct Entity
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityMeta getMeta()
|
EntityMeta getMeta() const
|
||||||
{
|
{
|
||||||
EntityMeta meta;
|
EntityMeta meta;
|
||||||
meta.block = gEM.getMetaData(&this);
|
meta.block = gEM.getMetaData(&this);
|
||||||
|
|
@ -66,15 +77,26 @@ struct EntityMeta
|
||||||
|
|
||||||
T* getComponent(T)() const
|
T* getComponent(T)() const
|
||||||
{
|
{
|
||||||
const (EntityManager.EntityInfo)* info = block.type_info;
|
/*const (EntityManager.EntityInfo)* info = block.type_info;
|
||||||
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
||||||
return null;
|
return null;
|
||||||
return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof);
|
return cast(T*)(cast(void*)block + info.deltas[T.component_id] + index * T.sizeof);*/
|
||||||
|
return cast(T*)getComponent(T.component_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* getComponent(ushort component_id) const
|
||||||
|
{
|
||||||
|
const (EntityManager.EntityInfo)* info = block.type_info;
|
||||||
|
|
||||||
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (cast(void*)block + info.deltas[component_id] + index * gEM.components[component_id].size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasComponent(ushort component_id)
|
bool hasComponent(ushort component_id) const
|
||||||
{
|
{
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
const EntityManager.EntityInfo* info = block.type_info;
|
||||||
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false;
|
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +128,15 @@ export struct EntityTemplate
|
||||||
if(T.component_id >= info.tmpl_deltas.length || info.tmpl_deltas[T.component_id] == ushort.max)return null;
|
if(T.component_id >= info.tmpl_deltas.length || info.tmpl_deltas[T.component_id] == ushort.max)return null;
|
||||||
return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
|
return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************************************************
|
||||||
|
Get specified component. If component doesn't exist function return null. Returned pointer is valid during EntityTemplate lifetime.
|
||||||
|
*/
|
||||||
|
void* getComponent(ushort component_id) const nothrow @nogc
|
||||||
|
{
|
||||||
|
if(component_id >= info.tmpl_deltas.length || info.tmpl_deltas[component_id] == ushort.max)return null;
|
||||||
|
return cast(void*)(entity_data.ptr + info.tmpl_deltas[component_id]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ struct IDManager
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
Get new ID.
|
Get new ID.
|
||||||
*/
|
*/
|
||||||
pragma(inline, false) EntityID getNewID() nothrow @nogc
|
EntityID getNewID() nothrow @nogc
|
||||||
{
|
{
|
||||||
int current = m_stack_top.atomicOp!"-="(1) + 1;
|
int current = m_stack_top.atomicOp!"-="(1) + 1;
|
||||||
if (current < 0)
|
if (current < 0)
|
||||||
|
|
@ -177,15 +177,9 @@ struct IDManager
|
||||||
if (m_last_id > m_ids_array.length)
|
if (m_last_id > m_ids_array.length)
|
||||||
{
|
{
|
||||||
uint begin = cast(uint) m_ids_array.length;
|
uint begin = cast(uint) m_ids_array.length;
|
||||||
Data[] new_array = Mallocator.makeArray!Data(begin + (m_blocks_count << 16));
|
|
||||||
memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof);
|
|
||||||
Mallocator.dispose(m_ids_array);
|
|
||||||
m_ids_array = new_array;
|
|
||||||
|
|
||||||
uint[] new_stack = Mallocator.makeArray!uint(m_ids_array.length);
|
m_ids_array = Mallocator.resizeArray(m_ids_array, begin + (m_blocks_count << 16));
|
||||||
memcpy(new_stack.ptr, m_free_stack.ptr, m_free_stack.length * uint.sizeof);
|
m_free_stack = Mallocator.resizeArray(m_free_stack, m_ids_array.length);
|
||||||
Mallocator.dispose(m_free_stack);
|
|
||||||
m_free_stack = new_stack;
|
|
||||||
|
|
||||||
foreach (block; m_blocks[0 .. m_blocks_count - 1])
|
foreach (block; m_blocks[0 .. m_blocks_count - 1])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -96,29 +96,7 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
foreach (ref system; systems)
|
foreach (ref system; systems)
|
||||||
{
|
{
|
||||||
system.disable();
|
system.destroy();
|
||||||
if (system.m_destroy)
|
|
||||||
(cast(void function(void*)) system.m_destroy)(system.m_system_pointer);
|
|
||||||
|
|
||||||
if (system.jobs)
|
|
||||||
Mallocator.dispose(system.jobs);
|
|
||||||
if (system.m_read_only_components)
|
|
||||||
Mallocator.dispose(system.m_read_only_components);
|
|
||||||
if (system.m_writable_components)
|
|
||||||
Mallocator.dispose(system.m_writable_components);
|
|
||||||
if (system.m_components)
|
|
||||||
Mallocator.dispose(system.m_components);
|
|
||||||
if (system.m_excluded_components)
|
|
||||||
Mallocator.dispose(system.m_excluded_components);
|
|
||||||
if (system.m_optional_components)
|
|
||||||
Mallocator.dispose(system.m_optional_components);
|
|
||||||
if (system.m_name)
|
|
||||||
Mallocator.dispose(system.m_name);
|
|
||||||
if (system.m_event_callers)
|
|
||||||
Mallocator.dispose(system.m_event_callers);
|
|
||||||
|
|
||||||
if (system.m_system_pointer)
|
|
||||||
Mallocator.dispose(system.m_system_pointer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (EntityInfo* info; &entities_infos.byValue)
|
foreach (EntityInfo* info; &entities_infos.byValue)
|
||||||
|
|
@ -382,6 +360,10 @@ export struct EntityManager
|
||||||
else
|
else
|
||||||
assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist.");
|
assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist.");
|
||||||
|
|
||||||
|
// enum SystemName = fullyQualifiedName!Sys;
|
||||||
|
enum SystemName = fullName!Sys;
|
||||||
|
//enum SystemName = Sys.stringof;
|
||||||
|
|
||||||
System system;
|
System system;
|
||||||
system.m_pass = pass;
|
system.m_pass = pass;
|
||||||
|
|
||||||
|
|
@ -418,9 +400,11 @@ export struct EntityManager
|
||||||
static if (Params.length == 2 && is(Params[0] == Entity*))
|
static if (Params.length == 2 && is(Params[0] == Entity*))
|
||||||
{
|
{
|
||||||
alias EventParamType = Params[1];
|
alias EventParamType = Params[1];
|
||||||
enum EventName = Unqual!(EventParamType).stringof;
|
enum EventName = fullName!(Unqual!(EventParamType));
|
||||||
|
// enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof;
|
||||||
ushort evt = events_map.get(cast(char[]) EventName, ushort.max);
|
ushort evt = events_map.get(cast(char[]) EventName, ushort.max);
|
||||||
assert(evt != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(evt != ushort.max,
|
||||||
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing event \"" ~ EventName ~ "\".");
|
~ "\" due to non existing event \"" ~ EventName ~ "\".");
|
||||||
|
|
||||||
callers[i].callback = cast(void*)&callEventHandler!(EventParamType);
|
callers[i].callback = cast(void*)&callEventHandler!(EventParamType);
|
||||||
|
|
@ -456,7 +440,7 @@ export struct EntityManager
|
||||||
uint writable_dep = 1;
|
uint writable_dep = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ComponentsCounts getComponentsCounts()()
|
static ComponentsCounts getComponentsCounts()
|
||||||
{
|
{
|
||||||
ComponentsCounts components_counts;
|
ComponentsCounts components_counts;
|
||||||
|
|
||||||
|
|
@ -479,7 +463,8 @@ export struct EntityManager
|
||||||
string name;
|
string name;
|
||||||
static if (isArray!MemberType)
|
static if (isArray!MemberType)
|
||||||
{ // Workaround. This code is never called with: not an array type, but compiler prints an error
|
{ // Workaround. This code is never called with: not an array type, but compiler prints an error
|
||||||
name = Unqual!(ForeachType!MemberType).stringof;
|
// name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof;
|
||||||
|
name = fullName!(Unqual!(ForeachType!MemberType));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_optional;
|
bool is_optional;
|
||||||
|
|
@ -679,7 +664,7 @@ export struct EntityManager
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ComponentsIndices!component_counts getComponentsInfo()()
|
static ComponentsIndices!component_counts getComponentsInfo()
|
||||||
{
|
{
|
||||||
ComponentsIndices!component_counts components_info;
|
ComponentsIndices!component_counts components_info;
|
||||||
|
|
||||||
|
|
@ -704,7 +689,9 @@ export struct EntityManager
|
||||||
string name;
|
string name;
|
||||||
static if (isArray!MemberType)
|
static if (isArray!MemberType)
|
||||||
{ // Workaround. This code is never called with: not an array type, but compiler prints an error
|
{ // Workaround. This code is never called with: not an array type, but compiler prints an error
|
||||||
name = Unqual!(ForeachType!MemberType).stringof;
|
// name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));
|
||||||
|
name = fullName!(Unqual!(ForeachType!MemberType));
|
||||||
|
//name = Unqual!(ForeachType!MemberType).stringof;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_optional;
|
bool is_optional;
|
||||||
|
|
@ -759,7 +746,8 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
foreach (str; Sys.ExcludedComponents)
|
foreach (str; Sys.ExcludedComponents)
|
||||||
{
|
{
|
||||||
components_info.addExcluded(CompInfo(str.stringof, str.stringof));
|
components_info.addExcluded(CompInfo(str.stringof, fullName!str));
|
||||||
|
// components_info.addExcluded(CompInfo(str.stringof, str.stringof));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -786,7 +774,7 @@ export struct EntityManager
|
||||||
|
|
||||||
enum ComponentsIndices!component_counts components_info = getComponentsInfo();
|
enum ComponentsIndices!component_counts components_info = getComponentsInfo();
|
||||||
|
|
||||||
static void genCompList()(ref System system, ref HashMap!(char[], ushort) components_map)
|
static void genCompList(ref System system, ref HashMap!(char[], ushort) components_map)
|
||||||
{
|
{
|
||||||
|
|
||||||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||||
|
|
@ -828,10 +816,10 @@ export struct EntityManager
|
||||||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component.");
|
~ "\" due to non existing component.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_components[iii] = comp;
|
system.m_components[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
@ -840,10 +828,10 @@ export struct EntityManager
|
||||||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component.");
|
~ "\" due to non existing component.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_excluded_components[iii] = comp;
|
system.m_excluded_components[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
@ -852,10 +840,10 @@ export struct EntityManager
|
||||||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component.");
|
~ "\" due to non existing component.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_optional_components[iii] = comp;
|
system.m_optional_components[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
@ -864,10 +852,10 @@ export struct EntityManager
|
||||||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component.");
|
~ "\" due to non existing component.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_read_only_components[iii] = comp;
|
system.m_read_only_components[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
@ -876,16 +864,16 @@ export struct EntityManager
|
||||||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component.");
|
~ "\" due to non existing component.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing component \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_writable_components[iii] = comp;
|
system.m_writable_components[iii] = comp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillInputData()(ref Sys.EntitiesData input_data, EntityInfo* info,
|
static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info,
|
||||||
EntitiesBlock* block, uint offset, uint entities_count, System* system)
|
EntitiesBlock* block, uint offset, uint entities_count, System* system)
|
||||||
{
|
{
|
||||||
//enum ComponentsIndices components_info = getComponentsInfo();
|
//enum ComponentsIndices components_info = getComponentsInfo();
|
||||||
|
|
@ -906,7 +894,9 @@ export struct EntityManager
|
||||||
input_data.thread_id = cast(typeof(input_data.thread_id))threadID();
|
input_data.thread_id = cast(typeof(input_data.thread_id))threadID();
|
||||||
}//*/
|
}//*/
|
||||||
|
|
||||||
static foreach (iii, comp_info; components_info.req)
|
///FIXME: should be "components_info.req()" but it's not compile with GCC
|
||||||
|
static foreach (iii, comp_info; components_info.m_req[0
|
||||||
|
.. components_info.m_req_counter])
|
||||||
{
|
{
|
||||||
__traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember,
|
__traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember,
|
||||||
Sys.EntitiesData, comp_info.name)))*)(
|
Sys.EntitiesData, comp_info.name)))*)(
|
||||||
|
|
@ -914,7 +904,8 @@ export struct EntityManager
|
||||||
.. entities_count];
|
.. entities_count];
|
||||||
}
|
}
|
||||||
|
|
||||||
static foreach (iii, comp_info; components_info.optional)
|
static foreach (iii, comp_info; components_info.m_optional[0
|
||||||
|
.. components_info.m_optional_counter])
|
||||||
{
|
{
|
||||||
if (system.m_optional_components[iii] < info.deltas.length
|
if (system.m_optional_components[iii] < info.deltas.length
|
||||||
&& info.deltas[system.m_optional_components[iii]] != 0)
|
&& info.deltas[system.m_optional_components[iii]] != 0)
|
||||||
|
|
@ -928,7 +919,7 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool checkOnUpdateParams()()
|
/*bool checkOnUpdateParams()
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
||||||
|
|
@ -1005,26 +996,30 @@ export struct EntityManager
|
||||||
else
|
else
|
||||||
entities_count = block.entities_count;
|
entities_count = block.entities_count;
|
||||||
|
|
||||||
assert(entities_count <= block.entities_count
|
if (entities_count > 0)
|
||||||
&& offset <= block.entities_count);
|
|
||||||
|
|
||||||
fillInputData(input_data, info, block, offset, entities_count, system);
|
|
||||||
|
|
||||||
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
|
||||||
{
|
{
|
||||||
input_data.thread_id = cast(typeof(input_data.thread_id)) data
|
assert(entities_count <= block.entities_count
|
||||||
.thread_id;
|
&& offset < block.entities_count);
|
||||||
|
assert(entities_count > offset);
|
||||||
|
|
||||||
|
fillInputData(input_data, info, block, offset, entities_count, system);
|
||||||
|
|
||||||
|
static if (hasMember!(Sys.EntitiesData, "thread_id"))
|
||||||
|
{
|
||||||
|
input_data.thread_id = cast(
|
||||||
|
typeof(input_data.thread_id)) data.thread_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static if (hasMember!(Sys.EntitiesData, "job_id"))
|
||||||
|
{
|
||||||
|
input_data.job_id = cast(typeof(input_data.job_id)) data.job_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//s.onUpdate(input_data);
|
||||||
|
(cast(typeof(&__traits(getOverloads, s,
|
||||||
|
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(
|
||||||
|
input_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (hasMember!(Sys.EntitiesData, "job_id"))
|
|
||||||
{
|
|
||||||
input_data.job_id = cast(typeof(input_data.job_id)) data.job_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
//s.onUpdate(input_data);
|
|
||||||
(cast(typeof(&__traits(getOverloads, s,
|
|
||||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
|
||||||
|
|
||||||
block = block.next_block;
|
block = block.next_block;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
blocks--;
|
blocks--;
|
||||||
|
|
@ -1115,6 +1110,32 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void catchEntityFilterFunction(string func_name, RetType = void)(void** member)
|
||||||
|
{
|
||||||
|
static if (hasMember!(Sys, func_name))
|
||||||
|
{
|
||||||
|
foreach (func; __traits(getOverloads, Sys, func_name))
|
||||||
|
{
|
||||||
|
static if ((Parameters!(func)).length == 1
|
||||||
|
&& is(Parameters!(func)[0] == EntityInfo*)
|
||||||
|
&& is(ReturnType!(func) == RetType))
|
||||||
|
{
|
||||||
|
static RetType callFunc(void* system_pointer, EntityInfo* info)
|
||||||
|
{
|
||||||
|
Sys* s = cast(Sys*) system_pointer;
|
||||||
|
static if (is(RetTyp == void))
|
||||||
|
mixin("s." ~ func_name ~ "(info)");
|
||||||
|
else
|
||||||
|
return mixin("s." ~ func_name ~ "(info)");
|
||||||
|
}
|
||||||
|
|
||||||
|
*member = cast(void*)&callFunc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
catchFunction!("onEnable")(&system.m_enable);
|
catchFunction!("onEnable")(&system.m_enable);
|
||||||
catchFunction!("onDisable")(&system.m_disable);
|
catchFunction!("onDisable")(&system.m_disable);
|
||||||
catchFunction!("onCreate")(&system.m_create);
|
catchFunction!("onCreate")(&system.m_create);
|
||||||
|
|
@ -1126,6 +1147,8 @@ export struct EntityManager
|
||||||
catchEntityFunction!("onRemoveEntity")(&system.m_remove_entity);
|
catchEntityFunction!("onRemoveEntity")(&system.m_remove_entity);
|
||||||
catchEntityFunction!("onChangeEntity")(&system.m_change_entity);
|
catchEntityFunction!("onChangeEntity")(&system.m_change_entity);
|
||||||
|
|
||||||
|
catchEntityFilterFunction!("filterEntity", bool)(&system.m_filter_entity);
|
||||||
|
|
||||||
system.m_system_pointer = cast(void*) Mallocator.make!Sys;
|
system.m_system_pointer = cast(void*) Mallocator.make!Sys;
|
||||||
system.m_priority = priority;
|
system.m_priority = priority;
|
||||||
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
|
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
|
||||||
|
|
@ -1148,10 +1171,10 @@ export struct EntityManager
|
||||||
ushort.max);
|
ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing dependency.");
|
~ "\" due to non existing dependency.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_readonly_dependencies[iii] = comp;
|
system.m_readonly_dependencies[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
@ -1161,21 +1184,20 @@ export struct EntityManager
|
||||||
ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max);
|
ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||||
version (D_BetterC)
|
version (D_BetterC)
|
||||||
assert(comp != ushort.max,
|
assert(comp != ushort.max,
|
||||||
"Can't register system \"" ~ Sys.stringof
|
"Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing dependency.");
|
~ "\" due to non existing dependency.");
|
||||||
else
|
else
|
||||||
assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof
|
assert(comp != ushort.max, "Can't register system \"" ~ SystemName
|
||||||
~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\".");
|
~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\".");
|
||||||
system.m_writable_dependencies[iii] = comp;
|
system.m_writable_dependencies[iii] = comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
ushort sys_id = systems_map.get(cast(char[]) Sys.stringof, ushort.max);
|
ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max);
|
||||||
if (sys_id < systems.length)
|
if (sys_id < systems.length)
|
||||||
{
|
{
|
||||||
systems[sys_id].disable();
|
system.m_name = systems[sys_id].m_name;
|
||||||
if (systems[sys_id].m_destroy)
|
systems[sys_id].m_name = null;
|
||||||
(cast(void function(void*)) systems[sys_id].m_destroy)(
|
systems[sys_id].destroy();
|
||||||
systems[sys_id].m_system_pointer);
|
|
||||||
|
|
||||||
if (system.m_create)
|
if (system.m_create)
|
||||||
(cast(void function(void*)) system.m_create)(system.m_system_pointer);
|
(cast(void function(void*)) system.m_create)(system.m_system_pointer);
|
||||||
|
|
@ -1183,12 +1205,11 @@ export struct EntityManager
|
||||||
system.enable();
|
system.enable();
|
||||||
|
|
||||||
system.m_id = sys_id;
|
system.m_id = sys_id;
|
||||||
system.m_name = systems[sys_id].m_name;
|
|
||||||
systems[sys_id] = system;
|
systems[sys_id] = system;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
system.m_name = Mallocator.makeArray(cast(char[]) Sys.stringof);
|
system.m_name = Mallocator.makeArray(cast(char[]) SystemName);
|
||||||
|
|
||||||
systems_map.add(system.m_name, cast(ushort) systems.length);
|
systems_map.add(system.m_name, cast(ushort) systems.length);
|
||||||
|
|
||||||
|
|
@ -1247,6 +1268,10 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
ComponentInfo info;
|
ComponentInfo info;
|
||||||
|
|
||||||
|
// enum ComponentName = fullyQualifiedName!Comp;
|
||||||
|
enum ComponentName = fullName!Comp;
|
||||||
|
// enum ComponentName = Comp.stringof;
|
||||||
|
|
||||||
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
|
static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort))
|
||||||
{
|
{
|
||||||
static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;");
|
static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;");
|
||||||
|
|
@ -1283,19 +1308,19 @@ export struct EntityManager
|
||||||
info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof);
|
info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof);
|
||||||
*cast(Comp*) info.init_data.ptr = Comp.init; // = Comp();
|
*cast(Comp*) info.init_data.ptr = Comp.init; // = Comp();
|
||||||
|
|
||||||
ushort comp_id = components_map.get(cast(char[]) Comp.stringof, ushort.max);
|
ushort comp_id = components_map.get(cast(char[]) ComponentName, ushort.max);
|
||||||
if (comp_id < components.length)
|
if (comp_id < components.length)
|
||||||
{
|
{
|
||||||
Comp.component_id = comp_id;
|
Comp.component_id = comp_id;
|
||||||
|
if (components[comp_id].init_data)
|
||||||
|
Mallocator.dispose(components[comp_id].init_data);
|
||||||
components[comp_id] = info;
|
components[comp_id] = info;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
components.add(info);
|
components.add(info);
|
||||||
Comp.component_id = cast(ushort)(components.length - 1);
|
Comp.component_id = cast(ushort)(components.length - 1);
|
||||||
char[] name = Mallocator.makeArray(cast(char[]) Comp.stringof);
|
char[] name = Mallocator.makeArray(cast(char[]) ComponentName);
|
||||||
/*char[] name = Mallocator.makeArray!char(Comp.stringof.length);
|
|
||||||
name[0..$] = Comp.stringof;*/
|
|
||||||
components_map.add(name, cast(ushort)(components.length - 1));
|
components_map.add(name, cast(ushort)(components.length - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1323,7 +1348,8 @@ export struct EntityManager
|
||||||
info.size = Ev.sizeof;
|
info.size = Ev.sizeof;
|
||||||
info.alignment = Ev.alignof;
|
info.alignment = Ev.alignof;
|
||||||
|
|
||||||
ushort event_id = events_map.get(Ev.stringof, ushort.max);
|
//ushort event_id = events_map.get(Ev.stringof, ushort.max);
|
||||||
|
ushort event_id = events_map.get(fullName!Ev, ushort.max);
|
||||||
if (event_id < events.length)
|
if (event_id < events.length)
|
||||||
{
|
{
|
||||||
Ev.event_id = event_id;
|
Ev.event_id = event_id;
|
||||||
|
|
@ -1332,26 +1358,31 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
events.add(info);
|
events.add(info);
|
||||||
Ev.event_id = cast(ushort)(events.length - 1);
|
Ev.event_id = cast(ushort)(events.length - 1);
|
||||||
events_map.add(Ev.stringof, cast(ushort)(events.length - 1));
|
// events_map.add(Ev.stringof, cast(ushort)(events.length - 1));
|
||||||
|
events_map.add(fullName!Ev, cast(ushort)(events.length - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export void callEntitiesFunction(Sys, T)(T func)
|
export void callEntitiesFunction(Sys, T)(T func)
|
||||||
{
|
{
|
||||||
|
//TODO: check if onUpdate function is good
|
||||||
Sys* s;
|
Sys* s;
|
||||||
static assert(isDelegate!func, "Function must be delegate.");
|
static assert(isDelegate!func, "Function must be delegate.");
|
||||||
static assert(__traits(hasMember, Sys, "EntitiesData"),
|
static assert(__traits(hasMember, Sys, "EntitiesData"),
|
||||||
"Can't call function with system which hasn't EntitesData structure.");
|
"Can't call function with system which hasn't EntitesData structure.");
|
||||||
|
///TODO: make possibly to call function to group without system with onUpdate function
|
||||||
static assert(__traits(hasMember, Sys, "onUpdate"),
|
static assert(__traits(hasMember, Sys, "onUpdate"),
|
||||||
"Can't call function with system which hasn't onUpdate function callback.");
|
"Can't call function with system which hasn't onUpdate function callback.");
|
||||||
static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
|
// static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
|
||||||
functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)),
|
// functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)),
|
||||||
"Function must match system update function.");
|
// "Function must match system update function."); FIXME: It's lead to crash on android build
|
||||||
static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type.");
|
static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type.");
|
||||||
|
|
||||||
System* system = getSystem(Sys.system_id);
|
System* system = getSystem(Sys.system_id);
|
||||||
assert(system != null,
|
assert(system != null,
|
||||||
"System must be registered in EntityManager before any funcion can be called.");
|
"System must be registered in EntityManager before any funcion can be called.");
|
||||||
|
if (!system.m_any_system_caller)
|
||||||
|
return;
|
||||||
|
|
||||||
foreach (info; system.m_any_system_caller.infos)
|
foreach (info; system.m_any_system_caller.infos)
|
||||||
{
|
{
|
||||||
|
|
@ -1479,21 +1510,28 @@ export struct EntityManager
|
||||||
if (first_block is null || blocks_count == 0)
|
if (first_block is null || blocks_count == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
//if this info will fill job
|
||||||
if ((blocks_count - 1) * info.max_entities + entities_count
|
if ((blocks_count - 1) * info.max_entities + entities_count
|
||||||
+ info.last_block.entities_count - first_elem >= entities_per_job)
|
+ info.last_block.entities_count - first_elem >= entities_per_job)
|
||||||
{
|
{
|
||||||
int reamaining_entities = (entities_per_job - entities_count - (
|
int reamaining_entities = (entities_per_job - entities_count - (
|
||||||
first_block.entities_count - first_elem));
|
first_block.entities_count - first_elem));
|
||||||
if (reamaining_entities >= 0)
|
|
||||||
|
//if first block don't fill job
|
||||||
|
if (reamaining_entities > 0)
|
||||||
{
|
{
|
||||||
|
//take as many full blocks as possible
|
||||||
int full_blocks_count = reamaining_entities / info.max_entities;
|
int full_blocks_count = reamaining_entities / info.max_entities;
|
||||||
EntitiesBlock* block = first_block;
|
EntitiesBlock* block = first_block;
|
||||||
foreach (i; 0 .. full_blocks_count + 1)
|
foreach (i; 0 .. full_blocks_count + 1)
|
||||||
block = block.next_block;
|
block = block.next_block;
|
||||||
|
|
||||||
|
//if full block + actual contained entities + remaining entities form first block > entities count per job
|
||||||
if (full_blocks_count * info.max_entities + entities_count + (
|
if (full_blocks_count * info.max_entities + entities_count + (
|
||||||
first_block.entities_count - first_elem) >= entities_per_job)
|
first_block.entities_count - first_elem) >= entities_per_job)
|
||||||
{
|
{
|
||||||
|
assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + (
|
||||||
|
first_block.entities_count - first_elem));
|
||||||
CallData data = CallData(caller.system_id, sys,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
info, sys.m_update_delegate, first_block,
|
info, sys.m_update_delegate, first_block,
|
||||||
cast(ushort)(full_blocks_count + 1),
|
cast(ushort)(full_blocks_count + 1),
|
||||||
|
|
@ -1508,6 +1546,8 @@ export struct EntityManager
|
||||||
entities_count += full_blocks_count * info.max_entities + (
|
entities_count += full_blocks_count * info.max_entities + (
|
||||||
first_block.entities_count - first_elem); // - first_elem;
|
first_block.entities_count - first_elem); // - first_elem;
|
||||||
uint last_elem = entities_per_job - entities_count; // + first_elem - 1;
|
uint last_elem = entities_per_job - entities_count; // + first_elem - 1;
|
||||||
|
assert(last_elem > 0);
|
||||||
|
assert(last_elem <= block.entities_count);
|
||||||
CallData data = CallData(caller.system_id, sys,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
info, sys.m_update_delegate, first_block,
|
info, sys.m_update_delegate, first_block,
|
||||||
cast(ushort)(full_blocks_count + 2),
|
cast(ushort)(full_blocks_count + 2),
|
||||||
|
|
@ -1515,19 +1555,31 @@ export struct EntityManager
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
first_elem = last_elem;
|
first_elem = last_elem;
|
||||||
blocks_count -= full_blocks_count + 1;
|
blocks_count -= full_blocks_count + 1;
|
||||||
assert(first_elem <= block.entities_count);
|
|
||||||
first_block = block;
|
first_block = block;
|
||||||
|
if (last_elem == block.entities_count)
|
||||||
|
{
|
||||||
|
assert(block.next_block == null);
|
||||||
|
first_block = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint last_elem = entities_per_job - entities_count;
|
uint last_elem = entities_per_job - entities_count;
|
||||||
|
assert(last_elem > 0);
|
||||||
CallData data = CallData(caller.system_id, sys,
|
CallData data = CallData(caller.system_id, sys,
|
||||||
info, sys.m_update_delegate, first_block, 1,
|
info, sys.m_update_delegate, first_block, 1,
|
||||||
cast(ushort) first_elem, cast(ushort)(first_elem + last_elem));
|
cast(ushort) first_elem, cast(ushort)(first_elem + last_elem));
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
first_elem += last_elem;
|
first_elem += last_elem;
|
||||||
assert(first_elem <= first_block.entities_count);
|
assert(first_elem <= first_block.entities_count);
|
||||||
|
//if job takes every entity, take next block
|
||||||
|
if (first_elem == first_block.entities_count)
|
||||||
|
{
|
||||||
|
first_elem = 0;
|
||||||
|
first_block = first_block.next_block;
|
||||||
|
blocks_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nextJob();
|
nextJob();
|
||||||
entities_count = 0;
|
entities_count = 0;
|
||||||
|
|
@ -1535,6 +1587,7 @@ export struct EntityManager
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//take whole info blocks
|
||||||
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate,
|
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate,
|
||||||
first_block, cast(ushort) blocks_count, cast(ushort) first_elem);
|
first_block, cast(ushort) blocks_count, cast(ushort) first_elem);
|
||||||
tmp_datas.add(data);
|
tmp_datas.add(data);
|
||||||
|
|
@ -1828,6 +1881,8 @@ export struct EntityManager
|
||||||
|
|
||||||
foreach (i, id; ids)
|
foreach (i, id; ids)
|
||||||
{
|
{
|
||||||
|
if (current_delta == 0)
|
||||||
|
current_delta = ushort.max;
|
||||||
alignNum(current_delta, components[id].alignment);
|
alignNum(current_delta, components[id].alignment);
|
||||||
info.deltas[id] = cast(ushort) current_delta;
|
info.deltas[id] = cast(ushort) current_delta;
|
||||||
current_delta += entites_in_block * components[id].size;
|
current_delta += entites_in_block * components[id].size;
|
||||||
|
|
@ -2008,6 +2063,9 @@ export struct EntityManager
|
||||||
is_:
|
is_:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///call Custom Entity Filter test if function exists
|
||||||
|
if(system.m_filter_entity && !(cast(bool function(void* system_pointer, EntityInfo* info) @nogc nothrow)system.m_filter_entity)(system, &entity))return;
|
||||||
|
|
||||||
entity.systems[system_id] = true;
|
entity.systems[system_id] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2050,30 +2108,8 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
System* system = &systems[system_id];
|
System* system = &systems[system_id];
|
||||||
|
|
||||||
if (system.m_excluded_components)
|
connectListenerToEntityInfo(info, system_id);
|
||||||
{
|
if(!info.systems[system_id])return;
|
||||||
foreach (id; system.m_excluded_components)
|
|
||||||
{
|
|
||||||
foreach (id2; info.components)
|
|
||||||
{
|
|
||||||
if (id == id2)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (id; system.m_components)
|
|
||||||
{
|
|
||||||
foreach (i2, id2; info.components)
|
|
||||||
{
|
|
||||||
if (id2 == id)
|
|
||||||
goto is_;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
is_:
|
|
||||||
}
|
|
||||||
|
|
||||||
info.systems[system_id] = true;
|
|
||||||
|
|
||||||
uint index = 0;
|
uint index = 0;
|
||||||
for (; index < passes[system.m_pass].system_callers.length; index++)
|
for (; index < passes[system.m_pass].system_callers.length; index++)
|
||||||
|
|
@ -2486,17 +2522,17 @@ export struct EntityManager
|
||||||
{
|
{
|
||||||
ushort size = components[comp].size;
|
ushort size = components[comp].size;
|
||||||
if (size != 0)
|
if (size != 0)
|
||||||
memcpy(cast(void*) new_block + info.deltas[comp] + size * new_id,
|
memcpy(cast(void*) new_block + info.deltas[comp] + new_id * size,
|
||||||
cast(void*) block + info.deltas[comp] + size * index, size);
|
cast(void*) block + info.deltas[comp] + size * index, size);
|
||||||
|
|
||||||
if (components[comp].create_callback)
|
if (components[comp].create_callback)
|
||||||
{
|
{
|
||||||
components[comp].create_callback(
|
components[comp].create_callback(
|
||||||
cast(void*) block + info.deltas[comp] + new_id * size);
|
cast(void*) new_block + info.deltas[comp] + new_id * size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_index == 1 && info.update_block == block)
|
if (new_index == 1 && info.update_block == new_block)
|
||||||
threads[threadID].infosToUpdate.add(info);
|
threads[threadID].infosToUpdate.add(info);
|
||||||
|
|
||||||
Entity* new_entity = cast(Entity*) start;
|
Entity* new_entity = cast(Entity*) start;
|
||||||
|
|
@ -2515,43 +2551,6 @@ export struct EntityManager
|
||||||
*/
|
*/
|
||||||
export Entity* addEntity(EntityTemplate* tmpl)
|
export Entity* addEntity(EntityTemplate* tmpl)
|
||||||
{
|
{
|
||||||
/*EntityInfo* info = tmpl.info;
|
|
||||||
|
|
||||||
ushort index = 0;
|
|
||||||
EntitiesBlock* block;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
block = findBlockWithFreeSpaceMT(info);
|
|
||||||
index = block.added_count.atomicOp!"+="(1);
|
|
||||||
}
|
|
||||||
while (block.entities_count + index > info.max_entities);
|
|
||||||
|
|
||||||
uint id = (block.entities_count + index - 1); //block.added_count);
|
|
||||||
|
|
||||||
void* data_begin = block.dataBegin();
|
|
||||||
void* start = data_begin + EntityID.sizeof * id;
|
|
||||||
|
|
||||||
foreach (comp; info.components)
|
|
||||||
{
|
|
||||||
memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id,
|
|
||||||
tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
|
|
||||||
|
|
||||||
if (components[comp].create_callback)
|
|
||||||
{
|
|
||||||
components[comp].create_callback(
|
|
||||||
cast(void*) block + info.deltas[comp] + id * components[comp].size);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index == 1)
|
|
||||||
threads[threadID].infosToUpdate.add(block);
|
|
||||||
|
|
||||||
Entity* entity = cast(Entity*) start;
|
|
||||||
entity.id = id_manager.getNewID();
|
|
||||||
id_manager.update(*entity); //entity.updateID();
|
|
||||||
|
|
||||||
return entity;*/
|
|
||||||
return addEntity(tmpl, null);
|
return addEntity(tmpl, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3100,12 +3099,12 @@ export struct EntityManager
|
||||||
swapData();
|
swapData();
|
||||||
|
|
||||||
has_work = false;
|
has_work = false;
|
||||||
// has_work |= updateBlocks();
|
has_work |= updateBlocks();
|
||||||
// has_work |= changeEntities();
|
// has_work |= changeEntities();
|
||||||
// has_work |= removeEntities();
|
// has_work |= removeEntities();
|
||||||
has_work |= updateEvents();
|
has_work |= updateEvents();
|
||||||
|
|
||||||
//id_manager.optimize();
|
id_manager.optimize();
|
||||||
has_work |= updateBlocks();
|
has_work |= updateBlocks();
|
||||||
has_work |= changeEntities();
|
has_work |= changeEntities();
|
||||||
has_work |= removeEntities();
|
has_work |= removeEntities();
|
||||||
|
|
@ -3493,6 +3492,12 @@ export struct EntityManager
|
||||||
return new_info;
|
return new_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export bool hasComponent(ushort component_id)
|
||||||
|
{
|
||||||
|
if(component_id >= deltas.length || !deltas[component_id])return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
export ~this() @nogc nothrow
|
export ~this() @nogc nothrow
|
||||||
{
|
{
|
||||||
if (components)
|
if (components)
|
||||||
|
|
@ -3501,6 +3506,10 @@ export struct EntityManager
|
||||||
Mallocator.dispose(deltas);
|
Mallocator.dispose(deltas);
|
||||||
if (tmpl_deltas)
|
if (tmpl_deltas)
|
||||||
Mallocator.dispose(tmpl_deltas);
|
Mallocator.dispose(tmpl_deltas);
|
||||||
|
if (comp_add_info)
|
||||||
|
Mallocator.dispose(comp_add_info);
|
||||||
|
if (comp_rem_info)
|
||||||
|
Mallocator.dispose(comp_rem_info);
|
||||||
if (systems)
|
if (systems)
|
||||||
Mallocator.dispose(systems);
|
Mallocator.dispose(systems);
|
||||||
if (add_listeners)
|
if (add_listeners)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@ struct SimpleVector
|
||||||
{
|
{
|
||||||
|
|
||||||
@disable this(this);
|
@disable this(this);
|
||||||
|
|
||||||
|
~this() nothrow @nogc
|
||||||
|
{
|
||||||
|
if(data)
|
||||||
|
Mallocator.dispose(data);
|
||||||
|
}
|
||||||
|
|
||||||
///Add element to vector
|
///Add element to vector
|
||||||
void add(ubyte el) nothrow @nogc
|
void add(ubyte el) nothrow @nogc
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ else version (D_BetterC)
|
||||||
{
|
{
|
||||||
private const uint max_alloca = 10000;
|
private const uint max_alloca = 10000;
|
||||||
private __gshared byte[max_alloca] alloca_array;
|
private __gshared byte[max_alloca] alloca_array;
|
||||||
private uint alloca_pos = 0;
|
private __gshared uint alloca_pos = 0;
|
||||||
export extern (C) void* __alloca(size_t length) @nogc nothrow
|
export extern (C) void* __alloca(size_t length) @nogc nothrow
|
||||||
{
|
{
|
||||||
if (alloca_pos + length > max_alloca)
|
if (alloca_pos + length > max_alloca)
|
||||||
|
|
@ -152,13 +152,86 @@ else
|
||||||
|
|
||||||
static struct Mallocator
|
static struct Mallocator
|
||||||
{
|
{
|
||||||
|
static T[] resizeArray(T)(T[] array, size_t length) nothrow @nogc
|
||||||
|
{
|
||||||
|
T[] ret;
|
||||||
|
|
||||||
|
if (length > array.length)
|
||||||
|
{
|
||||||
|
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
|
||||||
|
static if (__traits(isPOD, T))
|
||||||
|
{
|
||||||
|
__gshared immutable T init = T.init;
|
||||||
|
|
||||||
|
foreach (i; array.length .. ret.length)
|
||||||
|
{
|
||||||
|
memcpy(&ret[i], &init, T.sizeof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static import std.conv;
|
||||||
|
|
||||||
|
foreach (i; array.length .. ret.length)
|
||||||
|
{
|
||||||
|
std.conv.emplace(&ret[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static if (__traits(hasMember, T, "__xdtor"))
|
||||||
|
{
|
||||||
|
foreach (i; length .. array.length)
|
||||||
|
{
|
||||||
|
array[i].__xdtor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else static if (__traits(hasMember, T, "__dtor"))
|
||||||
|
{
|
||||||
|
foreach (i; length .. array.length)
|
||||||
|
{
|
||||||
|
array[i].__dtor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static T[] makeArray(T)(size_t length) nothrow @nogc
|
static T[] makeArray(T)(size_t length) nothrow @nogc
|
||||||
{
|
{
|
||||||
T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length];
|
T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length];
|
||||||
|
|
||||||
static if (__traits(isPOD, T))
|
static if (__traits(isPOD, T))
|
||||||
{
|
{
|
||||||
static immutable T init = T.init;
|
__gshared immutable T init = T.init;
|
||||||
|
|
||||||
|
foreach (i; 0 .. ret.length)
|
||||||
|
{
|
||||||
|
memcpy(&ret[i], &init, T.sizeof);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static import std.conv;
|
||||||
|
|
||||||
|
foreach (i; 0 .. ret.length)
|
||||||
|
{
|
||||||
|
std.conv.emplace(&ret[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T[] alignMakeArray(T)(size_t length, size_t alignment) nothrow @nogc
|
||||||
|
{
|
||||||
|
T[] ret = (cast(T*) alignAlloc(T.sizeof * length, alignment))[0 .. length];
|
||||||
|
|
||||||
|
static if (__traits(isPOD, T))
|
||||||
|
{
|
||||||
|
__gshared immutable T init = T.init;
|
||||||
|
|
||||||
foreach (i; 0 .. ret.length)
|
foreach (i; 0 .. ret.length)
|
||||||
{
|
{
|
||||||
|
|
@ -206,7 +279,7 @@ static struct Mallocator
|
||||||
|
|
||||||
static if (__traits(isPOD, T))
|
static if (__traits(isPOD, T))
|
||||||
{
|
{
|
||||||
static immutable T init = T.init;
|
__gshared immutable T init = T.init;
|
||||||
memcpy(ret, &init, T.sizeof);
|
memcpy(ret, &init, T.sizeof);
|
||||||
}
|
}
|
||||||
else static if (is(T == struct))
|
else static if (is(T == struct))
|
||||||
|
|
@ -228,13 +301,34 @@ static struct Mallocator
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dispose(T)(T object) nothrow @nogc
|
static void dispose(T)(T object)
|
||||||
{
|
{
|
||||||
static if (__traits(hasMember, T, "__xdtor"))
|
static if (isArray!T)
|
||||||
object.__xdtor();
|
{
|
||||||
else static if (__traits(hasMember, T, "__dtor"))
|
alias TT = PointerTarget!(typeof(object.ptr));
|
||||||
object.__dtor();
|
static if (!isPointer!TT)
|
||||||
free(cast(void*) object);
|
{
|
||||||
|
static if (__traits(hasMember, TT, "__xdtor"))
|
||||||
|
{
|
||||||
|
foreach (ref TT t; object)
|
||||||
|
t.__xdtor();
|
||||||
|
}
|
||||||
|
else static if (__traits(hasMember, TT, "__dtor"))
|
||||||
|
{
|
||||||
|
foreach (TT t; object)
|
||||||
|
t.__dtor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(cast(void*) object.ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static if (__traits(hasMember, T, "__xdtor"))
|
||||||
|
object.__xdtor();
|
||||||
|
else static if (__traits(hasMember, T, "__dtor"))
|
||||||
|
object.__dtor();
|
||||||
|
free(cast(void*) object);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alignDispose(T)(T object)
|
static void alignDispose(T)(T object)
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,38 @@ struct System
|
||||||
|
|
||||||
package:
|
package:
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
import bubel.ecs.std : Mallocator;
|
||||||
|
disable();
|
||||||
|
if (m_destroy)
|
||||||
|
(cast(void function(void*)) m_destroy)(m_system_pointer);
|
||||||
|
|
||||||
|
if (m_name)
|
||||||
|
Mallocator.dispose(m_name);
|
||||||
|
if (m_components)
|
||||||
|
Mallocator.dispose(m_components);
|
||||||
|
if (m_excluded_components)
|
||||||
|
Mallocator.dispose(m_excluded_components);
|
||||||
|
if (m_optional_components)
|
||||||
|
Mallocator.dispose(m_optional_components);
|
||||||
|
if (jobs)
|
||||||
|
Mallocator.dispose(jobs);
|
||||||
|
if (m_read_only_components)
|
||||||
|
Mallocator.dispose(m_read_only_components);
|
||||||
|
if (m_writable_components)
|
||||||
|
Mallocator.dispose(m_writable_components);
|
||||||
|
if (m_readonly_dependencies)
|
||||||
|
Mallocator.dispose(m_readonly_dependencies);
|
||||||
|
if (m_writable_dependencies)
|
||||||
|
Mallocator.dispose(m_writable_dependencies);
|
||||||
|
if (m_event_callers)
|
||||||
|
Mallocator.dispose(m_event_callers);
|
||||||
|
|
||||||
|
if (m_system_pointer)
|
||||||
|
Mallocator.dispose(m_system_pointer);
|
||||||
|
}
|
||||||
|
|
||||||
struct EventCaller
|
struct EventCaller
|
||||||
{
|
{
|
||||||
ushort id;
|
ushort id;
|
||||||
|
|
@ -162,6 +194,8 @@ package:
|
||||||
void* m_remove_entity;
|
void* m_remove_entity;
|
||||||
void* m_change_entity;
|
void* m_change_entity;
|
||||||
|
|
||||||
|
void* m_filter_entity;
|
||||||
|
|
||||||
//void function(ref EntityManager.CallData data) m_initialize;
|
//void function(ref EntityManager.CallData data) m_initialize;
|
||||||
//void function(ref EntityManager.CallData data) m_deinitilize;
|
//void function(ref EntityManager.CallData data) m_deinitilize;
|
||||||
void* m_initialize;
|
void* m_initialize;
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,35 @@ static long getIndexOfTypeInEntitiesData(EntitiesData, Type)()
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string attachParentName(alias T, string str)()
|
||||||
|
{
|
||||||
|
alias parent = __traits(parent, T);
|
||||||
|
enum parent_str = parent.stringof;
|
||||||
|
static if(parent_str[0..7] == "module ")
|
||||||
|
{
|
||||||
|
static if(__traits(compiles, __traits(parent, parent)))
|
||||||
|
{
|
||||||
|
return attachParentName!(parent, parent_str[7 .. $] ~ '.' ~ str);
|
||||||
|
}
|
||||||
|
else return parent_str[8 .. $] ~ '.' ~ str;
|
||||||
|
}
|
||||||
|
else static if(parent_str[0..8] == "package ")
|
||||||
|
{
|
||||||
|
static if(__traits(compiles, __traits(parent, parent)))
|
||||||
|
{
|
||||||
|
return attachParentName!(parent, parent_str[8 .. $] ~ '.' ~ str);
|
||||||
|
}
|
||||||
|
else return parent_str[8 .. $] ~ '.' ~ str;
|
||||||
|
}
|
||||||
|
else static if(__traits(compiles, __traits(parent, parent)))
|
||||||
|
{
|
||||||
|
return attachParentName!(parent, parent_str ~ '.' ~ str);
|
||||||
|
}
|
||||||
|
else return parent_str ~ '.' ~ str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string fullName(T)()
|
||||||
|
{
|
||||||
|
return attachParentName!(T, T.stringof);
|
||||||
|
}
|
||||||
162
tests/basic.d
162
tests/basic.d
|
|
@ -139,6 +139,7 @@ void afterEveryTest()
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_);
|
||||||
Entity* entity = gEM.addEntity(tmpl_);
|
Entity* entity = gEM.addEntity(tmpl_);
|
||||||
EntityMeta meta = entity.getMeta();
|
EntityMeta meta = entity.getMeta();
|
||||||
assert(meta.hasComponent(CInt.component_id));
|
assert(meta.hasComponent(CInt.component_id));
|
||||||
|
|
@ -157,6 +158,7 @@ unittest
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_);
|
||||||
assert(tmpl_.info.components.length == 3);
|
assert(tmpl_.info.components.length == 3);
|
||||||
assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof));
|
assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof));
|
||||||
assert(tmpl_.getComponent!CInt);
|
assert(tmpl_.getComponent!CInt);
|
||||||
|
|
@ -345,6 +347,7 @@ unittest
|
||||||
assert(*tmpl_7.getComponent!CLong == 10);
|
assert(*tmpl_7.getComponent!CLong == 10);
|
||||||
|
|
||||||
gEM.freeTemplate(tmpl_d);
|
gEM.freeTemplate(tmpl_d);
|
||||||
|
gEM.freeTemplate(tmpl_cp);
|
||||||
gEM.freeTemplate(tmpl_);
|
gEM.freeTemplate(tmpl_);
|
||||||
gEM.freeTemplate(tmpl_2);
|
gEM.freeTemplate(tmpl_2);
|
||||||
gEM.freeTemplate(tmpl_3);
|
gEM.freeTemplate(tmpl_3);
|
||||||
|
|
@ -368,6 +371,8 @@ unittest
|
||||||
assert(*tmpl_.getComponent!CInt == 1);
|
assert(*tmpl_.getComponent!CInt == 1);
|
||||||
assert(*tmpl_.getComponent!CFloat == 2.0);
|
assert(*tmpl_.getComponent!CFloat == 2.0);
|
||||||
assert(tmpl_.info == tmpl_2.info);
|
assert(tmpl_.info == tmpl_2.info);
|
||||||
|
gEM.freeTemplate(tmpl_);
|
||||||
|
gEM.freeTemplate(tmpl_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@("MultiRegister")
|
@("MultiRegister")
|
||||||
|
|
@ -401,7 +406,7 @@ unittest
|
||||||
System* ecs_system = gEM.getSystem(EmptySystem.system_id);
|
System* ecs_system = gEM.getSystem(EmptySystem.system_id);
|
||||||
assert(ecs_system !is null);
|
assert(ecs_system !is null);
|
||||||
assert(ecs_system.id == EmptySystem.system_id);
|
assert(ecs_system.id == EmptySystem.system_id);
|
||||||
assert(ecs_system.name == "EmptySystem");
|
assert(ecs_system.name == "tests.basic.EmptySystem");
|
||||||
|
|
||||||
gEM.begin();
|
gEM.begin();
|
||||||
|
|
||||||
|
|
@ -605,7 +610,7 @@ unittest
|
||||||
assert(ecs_system !is null);
|
assert(ecs_system !is null);
|
||||||
assert(ecs_system.id == LongAddSystem.system_id);
|
assert(ecs_system.id == LongAddSystem.system_id);
|
||||||
assert(ecs_system.priority == -1);
|
assert(ecs_system.priority == -1);
|
||||||
assert(ecs_system.name == "LongAddSystem");
|
assert(ecs_system.name == "tests.basic.LongAddSystem");
|
||||||
|
|
||||||
ushort[1] ids = [CLong.component_id];
|
ushort[1] ids = [CLong.component_id];
|
||||||
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
|
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
|
||||||
|
|
@ -897,7 +902,7 @@ unittest
|
||||||
{
|
{
|
||||||
struct TestSystem
|
struct TestSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System;
|
mixin ECS.System!64;
|
||||||
|
|
||||||
struct EntitiesData
|
struct EntitiesData
|
||||||
{
|
{
|
||||||
|
|
@ -1003,15 +1008,51 @@ unittest
|
||||||
assert(empty_system.update == 3);
|
assert(empty_system.update == 3);
|
||||||
system.entities = 0;
|
system.entities = 0;
|
||||||
|
|
||||||
foreach(i;0..10000)gEM.addEntity(tmpl);
|
// foreach(i;0..10000)gEM.addEntity(tmpl);
|
||||||
|
|
||||||
gEM.begin();
|
// gEM.begin();
|
||||||
|
|
||||||
gEM.updateMT("custom");
|
// gEM.updateMT("custom");
|
||||||
|
|
||||||
gEM.end();
|
// gEM.end();
|
||||||
|
|
||||||
assert(system.entities == 12001);
|
// assert(system.entities == 12001);
|
||||||
|
|
||||||
|
void clearEntities(TestSystem.EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
gEM.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gEM.callEntitiesFunction!TestSystem(&clearEntities);
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
|
foreach(i;0..2000)
|
||||||
|
{
|
||||||
|
gEM.addEntity(tmpl);
|
||||||
|
|
||||||
|
gEM.begin();
|
||||||
|
gEM.updateMT("custom");
|
||||||
|
gEM.end();
|
||||||
|
|
||||||
|
assert(system.entities == i+1);
|
||||||
|
system.entities = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(i;0..90000)gEM.addEntity(tmpl);
|
||||||
|
|
||||||
|
foreach(i;0..2000)
|
||||||
|
{
|
||||||
|
gEM.addEntity(tmpl);
|
||||||
|
|
||||||
|
gEM.begin();
|
||||||
|
gEM.updateMT("custom");
|
||||||
|
gEM.end();
|
||||||
|
|
||||||
|
assert(system.entities == i+92001);
|
||||||
|
system.entities = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
|
@ -1579,4 +1620,107 @@ unittest
|
||||||
assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id);
|
assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id);
|
||||||
assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.system_id);
|
assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.system_id);
|
||||||
assert(pass.system_callers[4].dependencies[1].system_id == TestSystem4.system_id);
|
assert(pass.system_callers[4].dependencies[1].system_id == TestSystem4.system_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@("CustomFilter")
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
struct TestSystem
|
||||||
|
{
|
||||||
|
mixin ECS.System;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
@optional CInt[] int_;
|
||||||
|
@optional CLong[] long_;
|
||||||
|
@optional CFloat[] float_;
|
||||||
|
@optional CDouble[] double_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filterEntity(EntityManager.EntityInfo* info)
|
||||||
|
{
|
||||||
|
if(!info.hasComponent(CInt.component_id))return false;
|
||||||
|
int one_from = 0;
|
||||||
|
if(info.hasComponent(CLong.component_id))one_from++;
|
||||||
|
if(info.hasComponent(CFloat.component_id))one_from++;
|
||||||
|
if(info.hasComponent(CDouble.component_id))one_from++;
|
||||||
|
if(one_from == 1)return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData entities)
|
||||||
|
{
|
||||||
|
updates++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint updates = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestSystem2
|
||||||
|
{
|
||||||
|
mixin ECS.System;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
@optional CInt[] int_;
|
||||||
|
@optional CLong[] long_;
|
||||||
|
@optional CFloat[] float_;
|
||||||
|
@optional CDouble[] double_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filterEntity(EntityManager.EntityInfo* info)
|
||||||
|
{
|
||||||
|
if(info.hasComponent(CInt.component_id) && info.hasComponent(CFloat.component_id) && !info.hasComponent(CLong.component_id) && !info.hasComponent(CDouble.component_id))return true;
|
||||||
|
if(info.hasComponent(CLong.component_id) && info.hasComponent(CDouble.component_id) && !info.hasComponent(CInt.component_id) && !info.hasComponent(CFloat.component_id))return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData entities)
|
||||||
|
{
|
||||||
|
updates++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint updates = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gEM.beginRegister();
|
||||||
|
|
||||||
|
gEM.registerSystem!TestSystem(0);
|
||||||
|
gEM.registerSystem!TestSystem2(1);
|
||||||
|
|
||||||
|
gEM.endRegister();
|
||||||
|
|
||||||
|
|
||||||
|
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CLong.component_id, CFloat.component_id, CDouble.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_);
|
||||||
|
EntityTemplate* tmpl_2 = gEM.allocateTemplate([CInt.component_id, CFloat.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_2);
|
||||||
|
EntityTemplate* tmpl_3 = gEM.allocateTemplate([CLong.component_id, CDouble.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_3);
|
||||||
|
EntityTemplate* tmpl_4 = gEM.allocateTemplate([CInt.component_id, CLong.component_id, CDouble.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_4);
|
||||||
|
EntityTemplate* tmpl_5 = gEM.allocateTemplate([CInt.component_id, CDouble.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_5);
|
||||||
|
EntityTemplate* tmpl_6 = gEM.allocateTemplate([CDouble.component_id].staticArray);
|
||||||
|
scope(exit)gEM.freeTemplate(tmpl_6);
|
||||||
|
|
||||||
|
gEM.addEntity(tmpl_);
|
||||||
|
gEM.addEntity(tmpl_2);
|
||||||
|
gEM.addEntity(tmpl_3);
|
||||||
|
gEM.addEntity(tmpl_4);
|
||||||
|
gEM.addEntity(tmpl_5);
|
||||||
|
gEM.addEntity(tmpl_6);
|
||||||
|
|
||||||
|
TestSystem* test_system = gEM.getSystem!TestSystem;
|
||||||
|
TestSystem2* test_system2 = gEM.getSystem!TestSystem2;
|
||||||
|
|
||||||
|
gEM.begin();
|
||||||
|
gEM.update();
|
||||||
|
gEM.end();
|
||||||
|
|
||||||
|
assert(test_system.updates == 2);
|
||||||
|
assert(test_system2.updates == 2);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -236,7 +236,7 @@ struct TestRunner(Args...)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
import core.exception : AssertError;
|
import core.exception : AssertError, RangeError;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
unittest_();
|
unittest_();
|
||||||
|
|
@ -249,6 +249,13 @@ struct TestRunner(Args...)
|
||||||
test.file_line = cast(int)error.line;
|
test.file_line = cast(int)error.line;
|
||||||
test.msg = copyString(error.msg);
|
test.msg = copyString(error.msg);
|
||||||
}
|
}
|
||||||
|
catch(RangeError error)
|
||||||
|
{
|
||||||
|
test.passed = false;
|
||||||
|
test.file = copyString(error.file);
|
||||||
|
test.file_line = cast(int)error.line;
|
||||||
|
test.msg = copyString(error.msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test.passed)
|
if (test.passed)
|
||||||
|
|
|
||||||
112
tests/tests.d
112
tests/tests.d
|
|
@ -93,6 +93,13 @@ struct TestEvent2
|
||||||
float a;
|
float a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct CPosition
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
}
|
||||||
|
|
||||||
static struct TestComp
|
static struct TestComp
|
||||||
{
|
{
|
||||||
mixin ECS.Component; //__gshared ushort component_id;
|
mixin ECS.Component; //__gshared ushort component_id;
|
||||||
|
|
@ -186,6 +193,52 @@ static struct TestComp5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EverySystem
|
||||||
|
{
|
||||||
|
mixin ECS.System;
|
||||||
|
|
||||||
|
struct EntitiesData
|
||||||
|
{
|
||||||
|
uint length;
|
||||||
|
Entity[] entity;
|
||||||
|
CPosition[] pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onUpdate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
data.pos[i].x++;
|
||||||
|
data.pos[i].y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void iterate(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
data.pos[i].x++;
|
||||||
|
data.pos[i].y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
gEM.removeEntity(data.entity[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addOne(EntitiesData data)
|
||||||
|
{
|
||||||
|
foreach(i;0..data.length)
|
||||||
|
{
|
||||||
|
gEM.addComponents(data.entity[i].id, TestComp2());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ChangeTestSystem
|
struct ChangeTestSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!16; //__gshared ushort system_id;
|
mixin ECS.System!16; //__gshared ushort system_id;
|
||||||
|
|
@ -648,6 +701,7 @@ else:
|
||||||
gEM.registerComponent!TestComp;
|
gEM.registerComponent!TestComp;
|
||||||
gEM.registerComponent!TestComp3;
|
gEM.registerComponent!TestComp3;
|
||||||
gEM.registerComponent!TestComp5;
|
gEM.registerComponent!TestComp5;
|
||||||
|
gEM.registerComponent!CPosition;
|
||||||
|
|
||||||
gEM.registerEvent!TestEvent;
|
gEM.registerEvent!TestEvent;
|
||||||
gEM.registerEvent!TestEvent2;
|
gEM.registerEvent!TestEvent2;
|
||||||
|
|
@ -669,6 +723,7 @@ else:
|
||||||
gEM.registerSystem!EmptySystem(2);
|
gEM.registerSystem!EmptySystem(2);
|
||||||
gEM.registerSystem!EmptyEventSystem(2);
|
gEM.registerSystem!EmptyEventSystem(2);
|
||||||
gEM.registerSystem!EventSystem(2);
|
gEM.registerSystem!EventSystem(2);
|
||||||
|
gEM.registerSystem!EverySystem(0);
|
||||||
//gEM.registerSystem!TestSystemWithHighPriority(100);
|
//gEM.registerSystem!TestSystemWithHighPriority(100);
|
||||||
//gEM.registerSystem!TestSystem2(0);
|
//gEM.registerSystem!TestSystem2(0);
|
||||||
gEM.endRegister();
|
gEM.endRegister();
|
||||||
|
|
@ -693,6 +748,62 @@ else:
|
||||||
//dur = (MonoTime.currTime - time).total!"usecs";
|
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||||
//writeln("Template allocating: ", dur, " usecs");
|
//writeln("Template allocating: ", dur, " usecs");
|
||||||
printf("Template allocating: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
printf("Template allocating: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
ushort[1] empty_ids = [CPosition.component_id];
|
||||||
|
EntityTemplate* tmpl_empty = gEM.allocateTemplate(empty_ids);
|
||||||
|
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
|
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
|
printf("Adding 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
gEM.commit();
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().iterate);
|
||||||
|
printf("Iterate 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
gEM.begin();
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
gEM.update();
|
||||||
|
printf("Iterate 1M entities (update): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
gEM.end();
|
||||||
|
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free);
|
||||||
|
gEM.commit();
|
||||||
|
printf("Deleting 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
|
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty);
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
|
printf("Adding 1M entities (prealloc): %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
gEM.commit();
|
||||||
|
time = Time.getUSecTime();
|
||||||
|
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().addOne);
|
||||||
|
gEM.commit();
|
||||||
|
printf("Adding 1M component: %f usecs\n", cast(float)(Time.getUSecTime() - time));
|
||||||
|
|
||||||
|
gEM.commit();
|
||||||
|
gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free);
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
time = Time.getUSecTime();
|
time = Time.getUSecTime();
|
||||||
|
|
||||||
EntityID entity;
|
EntityID entity;
|
||||||
|
|
@ -903,6 +1014,7 @@ else:
|
||||||
writeEntityComponents(gEM.getEntity(entity));
|
writeEntityComponents(gEM.getEntity(entity));
|
||||||
//import std.stdio;
|
//import std.stdio;
|
||||||
////writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
////writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
||||||
|
gEM.freeTemplate(tmpl_empty);
|
||||||
gEM.freeTemplate(tmpl);
|
gEM.freeTemplate(tmpl);
|
||||||
gEM.freeTemplate(tmpl2);
|
gEM.freeTemplate(tmpl2);
|
||||||
gEM.freeTemplate(copy_tempalte);
|
gEM.freeTemplate(copy_tempalte);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue