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
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -10,3 +10,4 @@
|
|||
!meson.build
|
||||
!meson_options.txt
|
||||
!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')
|
||||
2
demos/.gitignore
vendored
2
demos/.gitignore
vendored
|
|
@ -14,4 +14,6 @@
|
|||
!cimgui.bc
|
||||
!emscripten_shell.html
|
||||
!emscripten_multi_shell.html
|
||||
!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"],
|
||||
"lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"],
|
||||
"dflags-ldc" : [
|
||||
"--ffast-math"
|
||||
"--ffast-math",
|
||||
"-enable-cross-module-inlining"
|
||||
],
|
||||
"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
|
||||
module cimgui.cimgui;
|
||||
|
||||
import core.stdc.stdarg;
|
||||
// import core.stdc.stdarg;
|
||||
//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):
|
||||
|
||||
//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;
|
||||
} else {
|
||||
version(OSX) {
|
||||
enum const(char)*[] NAMES = [
|
||||
enum const(char)*[4] NAMES = [
|
||||
"../Frameworks/OpenGL.framework/OpenGL",
|
||||
"/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
|
||||
];
|
||||
} else {
|
||||
enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"];
|
||||
enum const(char)*[2] NAMES = ["libGL.so.1", "libGL.so"];
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
else version (Android)
|
||||
{
|
||||
version(LDC)
|
||||
{
|
||||
import ldc.attributes;
|
||||
@optStrategy("none")
|
||||
static void nop()
|
||||
{
|
||||
int i;
|
||||
i++;
|
||||
}
|
||||
nop();
|
||||
}
|
||||
else static assert(0);
|
||||
}
|
||||
else version(WebAssembly)
|
||||
{
|
||||
version(LDC)
|
||||
|
|
@ -381,8 +396,8 @@ version (MM_USE_POSIX_THREADS)
|
|||
void start(DG dg)
|
||||
{
|
||||
threadStart = dg;
|
||||
int ok = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
||||
if(!ok)handle = pthread_t();
|
||||
int err = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this);
|
||||
if(err)handle = pthread_t();
|
||||
//assert(ok == 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
private {
|
||||
SharedLib lib;
|
||||
SDLSupport loadedVersion;
|
||||
__gshared SharedLib lib;
|
||||
__gshared SDLSupport loadedVersion;
|
||||
}
|
||||
|
||||
void unloadSDL()
|
||||
|
|
@ -664,14 +664,14 @@ SDLSupport loadSDL(const(char)* libName)
|
|||
lib.bindSymbol(cast(void**)&SDL_HasColorKey, "SDL_HasColorKey");
|
||||
lib.bindSymbol(cast(void**)&SDL_GetDisplayOrientation, "SDL_GetDisplayOrientation");
|
||||
|
||||
version(linux) {
|
||||
lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority");
|
||||
}
|
||||
else version(Android) {
|
||||
version(Android) {
|
||||
lib.bindSymbol(cast(void**)&SDL_IsChromebook, "SDL_IsChromebook");
|
||||
lib.bindSymbol(cast(void**)&SDL_IsDeXMode, "SDL_IsDeXMode");
|
||||
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;
|
||||
else loadedVersion = SDLSupport.sdl209;
|
||||
|
|
|
|||
|
|
@ -229,8 +229,8 @@ else {
|
|||
}
|
||||
|
||||
private {
|
||||
SharedLib lib;
|
||||
SDLImageSupport loadedVersion;
|
||||
__gshared SharedLib lib;
|
||||
__gshared SDLImageSupport loadedVersion;
|
||||
}
|
||||
|
||||
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 game_core.basic;
|
||||
import game_core.job_updater;
|
||||
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.core;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.std;
|
||||
|
||||
import ecs_utils.gfx.renderer;
|
||||
|
|
@ -21,6 +22,7 @@ import glad.gl.gles2;
|
|||
import glad.gl.loader;
|
||||
|
||||
import gui.manager;
|
||||
import gui.tool_circle;
|
||||
|
||||
extern (C) :
|
||||
|
||||
|
|
@ -39,6 +41,16 @@ struct Mouse
|
|||
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
|
||||
{
|
||||
ECSJobUpdater* job_updater;
|
||||
|
|
@ -47,10 +59,10 @@ struct Launcher
|
|||
SDL_Window* window;
|
||||
SDL_GLContext gl_context;
|
||||
EntityManager* manager;
|
||||
bool function() loop;
|
||||
/*bool function() loop;
|
||||
void function() end;
|
||||
void function(SDL_Event*) event;
|
||||
void function(vec2, Tool, int) tool;
|
||||
void function(SDL_Event*) event;*/
|
||||
//void function(vec2, Tool, int, bool) tool;
|
||||
float scalling;
|
||||
ivec2 window_size = ivec2(1024,768);
|
||||
Renderer renderer;
|
||||
|
|
@ -65,15 +77,20 @@ struct Launcher
|
|||
vec2 render_position;
|
||||
|
||||
Tool used_tool;
|
||||
int tool_size = 0;
|
||||
int tool_size = 100;
|
||||
float tool_repeat = 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;
|
||||
|
||||
float windows_alpha = 0.75;
|
||||
|
||||
const (char)* tips;
|
||||
//const (char)* tips;
|
||||
|
||||
bool show_stat_wnd = true;
|
||||
bool show_tips = true;
|
||||
|
|
@ -93,17 +110,19 @@ struct Launcher
|
|||
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();
|
||||
//launcher.ent
|
||||
|
||||
if(this.end)this.end();
|
||||
|
||||
manager.begin();
|
||||
manager.update("clean");
|
||||
manager.end();
|
||||
|
||||
if(this.demo.deinitialize)this.demo.deinitialize();
|
||||
|
||||
foreach(ref system; manager.systems)
|
||||
{
|
||||
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(CleanSystem.system_id).enable();//*/
|
||||
|
||||
if(start)start();
|
||||
this.loop = loop;
|
||||
if(callbacks.register)callbacks.register();
|
||||
if(callbacks.initialize)callbacks.initialize();
|
||||
demo = callbacks;
|
||||
/*this.loop = loop;
|
||||
this.end = end;
|
||||
this.event = event;
|
||||
this.tips = tips;
|
||||
this.tool = tool;
|
||||
this.tips = tips;*/
|
||||
//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)
|
||||
|
|
@ -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)
|
||||
{
|
||||
__gshared double time = 0;
|
||||
|
|
@ -203,18 +386,43 @@ void mainLoop(void* arg)
|
|||
temp_fps = 0;
|
||||
}
|
||||
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
version(WebAssembly)ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
else ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
if(launcher.event)launcher.event(&event);
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
if(launcher.demo.event)launcher.demo.event(&event);
|
||||
if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) {
|
||||
quit();
|
||||
*cast(bool*)arg = false;
|
||||
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)
|
||||
{
|
||||
switch(event.window.event)
|
||||
|
|
@ -239,9 +447,12 @@ void mainLoop(void* arg)
|
|||
case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;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)
|
||||
|
|
@ -257,17 +468,67 @@ void mainLoop(void* arg)
|
|||
else if(event.type == SDL_MOUSEMOTION)
|
||||
{
|
||||
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;
|
||||
launcher.repeat_time += launcher.delta_time;
|
||||
if(launcher.used_tool != Tool.entity_spawner || !mode)
|
||||
{
|
||||
if(launcher.repeat_time > range)launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode);
|
||||
while(launcher.repeat_time > range)launcher.repeat_time -= range;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(launcher.repeat_time > range)
|
||||
{
|
||||
launcher.repeat_time -= range;
|
||||
launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size);
|
||||
launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +539,8 @@ void mainLoop(void* arg)
|
|||
}
|
||||
else
|
||||
{
|
||||
ImGuiImplOpenGL2NewFrame();
|
||||
//ImGuiImplOpenGL2NewFrame();
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGuiImplSDL2NewFrame(launcher.window);
|
||||
}
|
||||
|
||||
|
|
@ -301,17 +563,32 @@ void mainLoop(void* arg)
|
|||
if(igMenuItemBool("Simpe",null,false,true))
|
||||
{
|
||||
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))
|
||||
{
|
||||
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;
|
||||
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();
|
||||
}
|
||||
|
|
@ -344,22 +621,11 @@ void mainLoop(void* arg)
|
|||
}
|
||||
if(igBeginMenu("Show",true))
|
||||
{
|
||||
if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true))
|
||||
{
|
||||
launcher.show_stat_wnd = !launcher.show_stat_wnd;
|
||||
}
|
||||
else if(igMenuItemBool("Demo",null,launcher.show_demo_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;
|
||||
}
|
||||
igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true);
|
||||
igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true);
|
||||
igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true);
|
||||
igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true);
|
||||
igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true);
|
||||
igEndMenu();
|
||||
}
|
||||
if(igBeginMenu("Style",true))
|
||||
|
|
@ -456,7 +722,7 @@ void mainLoop(void* arg)
|
|||
igSetNextWindowBgAlpha(launcher.windows_alpha);
|
||||
if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings))
|
||||
{
|
||||
igTextWrapped(launcher.tips);
|
||||
igTextWrapped(launcher.demo.tips);
|
||||
}
|
||||
igEnd();
|
||||
}
|
||||
|
|
@ -464,20 +730,22 @@ void mainLoop(void* arg)
|
|||
if(launcher.show_demo_wnd)
|
||||
{
|
||||
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))
|
||||
{
|
||||
ImDrawList* draw_list = igGetWindowDrawList();
|
||||
//igBeginGroup();
|
||||
igBeginGroup();
|
||||
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);
|
||||
//igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow);
|
||||
//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);
|
||||
igBeginGroup();
|
||||
if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0))
|
||||
{
|
||||
if(igSelectable("Entity spawner",false,0,ImVec2(0,0)))
|
||||
|
|
@ -494,14 +762,44 @@ void mainLoop(void* arg)
|
|||
}
|
||||
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);
|
||||
igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4);
|
||||
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);
|
||||
}
|
||||
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();
|
||||
//igEndChildFrame();
|
||||
|
|
@ -517,7 +815,8 @@ void mainLoop(void* arg)
|
|||
|
||||
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);
|
||||
if(igBegin("Profile",&launcher.show_profile_wnd,0))
|
||||
{
|
||||
|
|
@ -565,7 +864,7 @@ void mainLoop(void* arg)
|
|||
|
||||
double loop_time = launcher.getTime();
|
||||
launcher.job_updater.pool.tryWaitCount = 10000;
|
||||
if(launcher.loop && !launcher.loop())
|
||||
if(launcher.demo.loop && !launcher.demo.loop())
|
||||
{
|
||||
quit();
|
||||
*cast(bool*)arg = false;
|
||||
|
|
@ -578,6 +877,8 @@ void mainLoop(void* arg)
|
|||
launcher.renderer.present();
|
||||
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 uint plot_samples = 0;
|
||||
plot_time += launcher.delta_time;
|
||||
|
|
@ -632,7 +933,9 @@ void mainLoop(void* arg)
|
|||
|
||||
igRender();
|
||||
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.present();
|
||||
|
|
@ -643,24 +946,64 @@ void mainLoop(void* arg)
|
|||
|
||||
void quit()
|
||||
{
|
||||
import game_core.rendering : TexCoordsManager;
|
||||
launcher.gui_manager.clear();
|
||||
Mallocator.dispose(launcher.gui_manager);
|
||||
|
||||
if(launcher.demo.deinitialize)launcher.demo.deinitialize();
|
||||
|
||||
launcher.manager.destroy();
|
||||
launcher.manager = null;
|
||||
|
||||
TexCoordsManager.destroy();
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
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)
|
||||
{
|
||||
printf("SDL could not initialize! SDL_Error: %s", SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_version 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);
|
||||
|
|
@ -669,6 +1012,7 @@ int main(int argc, char** argv)
|
|||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
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_MaximizeWindow(launcher.window);
|
||||
|
||||
launcher.gl_context = SDL_GL_CreateContext(launcher.window);
|
||||
launcher.context = igCreateContext(null);
|
||||
|
|
@ -692,6 +1036,21 @@ int main(int argc, char** argv)
|
|||
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
|
||||
{
|
||||
gladLoadGL();
|
||||
|
|
@ -700,17 +1059,19 @@ int main(int argc, char** argv)
|
|||
printf("ImGui initialization failed!");
|
||||
return -2;
|
||||
}
|
||||
if(!ImGuiImplOpenGL2Init())
|
||||
//if(!ImGuiImplOpenGL2Init())
|
||||
if(!ImGui_ImplOpenGL3_Init("#version 120"))
|
||||
{
|
||||
printf("ImGui OpenGL initialization failed!");
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
ImFontConfig* config = ImFontConfig_ImFontConfig();
|
||||
//ImFontConfig* config = ImFontConfig_ImFontConfig();
|
||||
ImGuiIO* io = igGetIO();
|
||||
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);
|
||||
|
||||
|
|
@ -728,14 +1089,19 @@ int main(int argc, char** argv)
|
|||
|
||||
launcher.manager.registerPass("clean");
|
||||
|
||||
launcher.manager.registerComponent!CLocation;
|
||||
|
||||
launcher.manager.registerSystem!CountSystem(10000);
|
||||
launcher.manager.registerSystem!CleanSystem(0,"clean");
|
||||
launcher.manager.registerSystem!IteratorSystem(0,"clean");
|
||||
|
||||
launcher.manager.endRegister();
|
||||
|
||||
loadGFX();
|
||||
|
||||
launcher.renderer.initialize();
|
||||
import game_core.rendering : TexCoordsManager;
|
||||
TexCoordsManager.initialize();
|
||||
|
||||
import mmutils.thread_pool : ThreadPool;
|
||||
launcher.threads = ThreadPool.getCPUCoresCount();
|
||||
|
|
@ -746,8 +1112,14 @@ int main(int argc, char** argv)
|
|||
{
|
||||
import demos.simple;
|
||||
import demos.space_invaders;
|
||||
// launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips);
|
||||
launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips);
|
||||
import demos.particles;
|
||||
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;
|
||||
|
|
@ -775,8 +1147,6 @@ int main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
EntityManager.destroy();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -792,7 +1162,7 @@ void loadGFX()
|
|||
Texture.__loadBackend();
|
||||
Renderer.__loadBackend();
|
||||
|
||||
GfxConfig.materials = Mallocator.makeArray!Material(1);
|
||||
GfxConfig.materials = Mallocator.makeArray!Material(3);
|
||||
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];
|
||||
|
|
@ -839,7 +1209,93 @@ void loadGFX()
|
|||
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);
|
||||
glBindBuffer(GL_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 cimgui.cimgui;
|
||||
|
||||
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;
|
||||
|
||||
extern(C):
|
||||
|
||||
struct Simple
|
||||
{
|
||||
__gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window.";
|
||||
enum float px = 1.0/512.0;
|
||||
|
||||
EntityTemplate* tmpl;
|
||||
Texture texture;
|
||||
/*#######################################################################################################################
|
||||
------------------------------------------------ Components ------------------------------------------------------------------
|
||||
#######################################################################################################################*/
|
||||
|
||||
bool move_system = true;
|
||||
bool draw_system = true;
|
||||
}
|
||||
|
||||
struct CLocation
|
||||
/*struct CLocation
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
alias location this;
|
||||
|
||||
vec2 location;
|
||||
}
|
||||
|
||||
struct CTexture
|
||||
{
|
||||
mixin ECS.Component;
|
||||
|
||||
Texture tex;
|
||||
}
|
||||
}*/
|
||||
|
||||
/*#######################################################################################################################
|
||||
------------------------------------------------ Systems ------------------------------------------------------------------
|
||||
#######################################################################################################################*/
|
||||
/*
|
||||
struct DrawSystem
|
||||
{
|
||||
mixin ECS.System!32;
|
||||
|
|
@ -54,22 +49,29 @@ struct DrawSystem
|
|||
uint length;
|
||||
//uint thread_id;
|
||||
uint job_id;
|
||||
@readonly CTexture[] textures;
|
||||
@readonly CLocation[] locations;
|
||||
}
|
||||
|
||||
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(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)
|
||||
{
|
||||
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);
|
||||
// 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(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1));
|
||||
}
|
||||
//if(data.thread_id == 0)launcher.renderer.pushData();
|
||||
draw_data.position = data.locations[i];
|
||||
draw_data.depth = cast(ushort)(data.locations[i].y);
|
||||
launcher.renderer.draw(draw_data);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
struct MoveSystem
|
||||
{
|
||||
|
|
@ -85,47 +87,67 @@ struct MoveSystem
|
|||
{
|
||||
foreach(i; 0..data.length)
|
||||
{
|
||||
data.locations[i].location.y = data.locations[i].location.y + 1;
|
||||
if(data.locations[i].location.y > 300)data.locations[i].location.y = 0;
|
||||
data.locations[i].y = data.locations[i].y + 1;
|
||||
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;
|
||||
|
||||
void simpleStart()
|
||||
void simpleRegister()
|
||||
{
|
||||
simple = Mallocator.make!Simple;
|
||||
|
||||
simple.texture.create();
|
||||
simple.texture.load("assets/textures/buckler.png");
|
||||
simple.texture.load("assets/textures/atlas.png");
|
||||
|
||||
launcher.manager.beginRegister();
|
||||
|
||||
registerRenderingModule(launcher.manager);
|
||||
|
||||
launcher.manager.registerComponent!CLocation;
|
||||
launcher.manager.registerComponent!CTexture;
|
||||
|
||||
launcher.manager.registerSystem!MoveSystem(0);
|
||||
launcher.manager.registerSystem!DrawSystem(1);
|
||||
// launcher.manager.registerSystem!DrawSystem(1);
|
||||
|
||||
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");
|
||||
|
||||
ushort[2] components = [CLocation.component_id, CTexture.component_id];
|
||||
simple.tmpl = launcher.manager.allocateTemplate(components);
|
||||
CTexture* tex_comp = simple.tmpl.getComponent!CTexture;
|
||||
tex_comp.tex = simple.texture;
|
||||
CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||
simple.tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CDrawDefault.component_id].staticArray);
|
||||
//*simple.tmpl.getComponent!CTexCoordsIndex = TexCoordsManager.instance.getCoordIndex(vec4(0,48,16,16)*px);
|
||||
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||
|
||||
launcher.gui_manager.addTemplate(simple.tmpl, "Basic");
|
||||
|
||||
foreach(i; 0..10)
|
||||
foreach(j; 0..10)
|
||||
{
|
||||
loc_comp.location = vec2(i*16+64,j*16+64);
|
||||
launcher.manager.addEntity(simple.tmpl);
|
||||
//loc_comp.value = vec2(i*16+64,j*16+64);
|
||||
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -140,46 +162,15 @@ void simpleEnd()
|
|||
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)
|
||||
{
|
||||
/*if(event.type == event.button)
|
||||
{
|
||||
vec2 position = vec2(event.button.x, event.button.y);
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
void spawnEntity()
|
||||
{
|
||||
CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||
loc_comp.location = vec2(randomf() * 400,0);
|
||||
launcher.manager.addEntity(simple.tmpl);
|
||||
//CLocation* loc_comp = simple.tmpl.getComponent!CLocation;
|
||||
//loc_comp.value = vec2(randomf() * 400,0);
|
||||
launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray);
|
||||
}
|
||||
|
||||
bool simpleLoop()
|
||||
|
|
@ -188,7 +179,7 @@ bool simpleLoop()
|
|||
|
||||
if(launcher.getKeyState(SDL_SCANCODE_SPACE))
|
||||
{
|
||||
foreach(i;0..1)spawnEntity();
|
||||
foreach(i;0..20)spawnEntity();
|
||||
}
|
||||
|
||||
launcher.manager.begin();
|
||||
|
|
@ -206,3 +197,14 @@ bool simpleLoop()
|
|||
|
||||
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 cimgui.cimgui;
|
||||
|
||||
import bubel.ecs.attributes;
|
||||
import bubel.ecs.core;
|
||||
import bubel.ecs.entity;
|
||||
|
|
@ -13,10 +11,14 @@ import bubel.ecs.manager;
|
|||
import bubel.ecs.std;
|
||||
import bubel.ecs.vector;
|
||||
|
||||
import cimgui.cimgui;
|
||||
|
||||
import ecs_utils.gfx.texture;
|
||||
import ecs_utils.math.vector;
|
||||
import ecs_utils.utils;
|
||||
|
||||
import game_core.basic;
|
||||
|
||||
//import std.array : staticArray;
|
||||
|
||||
enum float px = 1.0/512.0;
|
||||
|
|
@ -31,22 +33,6 @@ struct MapElement
|
|||
apple = 1,
|
||||
wall = 2,
|
||||
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;
|
||||
EntityID id;
|
||||
|
|
@ -86,7 +72,7 @@ struct Snake
|
|||
bool move_system = true;
|
||||
bool draw_system = true;
|
||||
|
||||
const int map_size = 18;
|
||||
enum int map_size = 18;
|
||||
|
||||
MapElement[map_size * map_size] map;
|
||||
|
||||
|
|
@ -97,7 +83,7 @@ struct Snake
|
|||
if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl);
|
||||
if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl);
|
||||
if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle);
|
||||
texture.destory();
|
||||
texture.destroy();
|
||||
}
|
||||
|
||||
MapElement element(ivec2 pos)
|
||||
|
|
@ -129,10 +115,7 @@ struct Snake
|
|||
}
|
||||
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
|
||||
}
|
||||
//CILocation* location = apple_tmpl.getComponent!CILocation;
|
||||
//*location = random_pos;
|
||||
//Entity* apple =
|
||||
launcher.manager.addEntity(apple_tmpl,[CILocation(random_pos).ref_].staticArray);
|
||||
launcher.manager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -158,14 +141,14 @@ struct CILocation
|
|||
ivec2 location;
|
||||
}
|
||||
|
||||
struct CLocation
|
||||
{
|
||||
mixin ECS.Component;
|
||||
// struct CLocation
|
||||
// {
|
||||
// mixin ECS.Component;
|
||||
|
||||
alias location this;
|
||||
// alias location this;
|
||||
|
||||
vec2 location = vec2(0,0);
|
||||
}
|
||||
// vec2 location = vec2(0,0);
|
||||
// }
|
||||
|
||||
struct CSnake
|
||||
{
|
||||
|
|
@ -252,10 +235,10 @@ struct CMovement
|
|||
Direction direction;
|
||||
}
|
||||
|
||||
struct CInput
|
||||
{
|
||||
mixin ECS.Component;
|
||||
}
|
||||
// struct CInput
|
||||
// {
|
||||
// mixin ECS.Component;
|
||||
// }
|
||||
|
||||
struct AppleSystem
|
||||
{
|
||||
|
|
@ -264,8 +247,8 @@ struct AppleSystem
|
|||
struct EntitiesData
|
||||
{
|
||||
uint length;
|
||||
@readonly Entity[] entities;
|
||||
@readonly CApple[] movement;
|
||||
@readonly Entity[] entity;
|
||||
@readonly CApple[] apple;
|
||||
@readonly CILocation[] location;
|
||||
}
|
||||
|
||||
|
|
@ -273,7 +256,17 @@ struct AppleSystem
|
|||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
case MapElement.Type.apple:
|
||||
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)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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_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_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_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0x80808080, 0);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_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_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_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0x80808080, 0);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.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,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:draw_data.coords = vec4(0,112,16,16)*px;break;
|
||||
case SnakePart.tail_left:draw_data.coords = vec4(32,112,16,16)*px;break;
|
||||
case SnakePart.tail_right:draw_data.coords = vec4(0,144,16,16)*px;break;
|
||||
case SnakePart.turn_ld:draw_data.coords = vec4(64,128,16,16)*px;break;
|
||||
case SnakePart.turn_lu:draw_data.coords = vec4(32,144,16,16)*px;break;
|
||||
case SnakePart.turn_rd:draw_data.coords = vec4(16,144,16,16)*px;break;
|
||||
case SnakePart.turn_ru:draw_data.coords = vec4(64,112,16,16)*px;break;
|
||||
case SnakePart.vertical:draw_data.coords = vec4(16,128,16,16)*px;break;
|
||||
case SnakePart.horizontal:draw_data.coords = vec4(48,128,16,16)*px;break;
|
||||
}
|
||||
launcher.renderer.draw(draw_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)
|
||||
{
|
||||
const (CSnake)* snake = &data.snake[i];
|
||||
scope vec2 loc = cast(vec2)(data.location[i].location * 16);
|
||||
draw_data.position = loc;
|
||||
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.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.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.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.up:draw_data.coords = vec4(48,112,16,16)*px;break;
|
||||
case CMovement.Direction.down:draw_data.coords = vec4(48,144,16,16)*px;break;
|
||||
case CMovement.Direction.left:draw_data.coords = vec4(0,128,16,16)*px;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)
|
||||
{
|
||||
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;
|
||||
|
||||
void snakeStart()
|
||||
void snakeRegister()
|
||||
{
|
||||
import game_core.rendering;
|
||||
|
||||
snake = Mallocator.make!Snake;
|
||||
|
||||
snake.texture.create();
|
||||
|
|
@ -763,6 +862,8 @@ void snakeStart()
|
|||
|
||||
launcher.manager.registerPass("fixed");
|
||||
|
||||
registerRenderingModule(launcher.manager);
|
||||
|
||||
launcher.manager.registerComponent!CLocation;
|
||||
launcher.manager.registerComponent!CILocation;
|
||||
launcher.manager.registerComponent!CSnake;
|
||||
|
|
@ -776,7 +877,6 @@ void snakeStart()
|
|||
launcher.manager.registerSystem!MoveSystem(0,"fixed");
|
||||
launcher.manager.registerSystem!InputSystem(-100);
|
||||
launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
|
||||
launcher.manager.registerSystem!AppleSystem(-1,"fixed");
|
||||
launcher.manager.registerSystem!AnimationRenderSystem(100);
|
||||
launcher.manager.registerSystem!AnimationSystem(-1);
|
||||
launcher.manager.registerSystem!ParticleSystem(-1);
|
||||
|
|
@ -784,7 +884,24 @@ void snakeStart()
|
|||
launcher.manager.registerSystem!DrawAppleSystem(99);
|
||||
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();
|
||||
}
|
||||
|
||||
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(InputSystem.system_id,"Input System");
|
||||
|
|
@ -793,19 +910,19 @@ void snakeStart()
|
|||
launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation 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(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);
|
||||
|
||||
{
|
||||
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);
|
||||
//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);
|
||||
}
|
||||
|
||||
{
|
||||
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;
|
||||
canim.frames = snake.snake_destroy_particle_frames;
|
||||
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.addApple();
|
||||
}
|
||||
|
|
@ -824,13 +941,6 @@ void snakeStart()
|
|||
|
||||
MoveSystem* move_system = launcher.manager.getSystem!MoveSystem();
|
||||
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()
|
||||
|
|
@ -839,39 +949,6 @@ void snakeEnd()
|
|||
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)
|
||||
{
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
/*if(launcher.show_demo_wnd)
|
||||
{
|
||||
igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
||||
igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
|
||||
if(igBegin("Snake",&launcher.show_demo_wnd,0))
|
||||
{
|
||||
// if(launcher.show_demo_wnd)
|
||||
// {
|
||||
// igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
|
||||
// igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
|
||||
// if(igBegin("Snake",&launcher.show_demo_wnd,0))
|
||||
// {
|
||||
|
||||
}
|
||||
igEnd();
|
||||
}*/
|
||||
// }
|
||||
// igEnd();
|
||||
// }
|
||||
|
||||
launcher.manager.begin();
|
||||
|
||||
|
|
@ -901,9 +978,9 @@ bool snakeLoop()
|
|||
if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3;
|
||||
else time += delta_time;
|
||||
|
||||
while(time > 100)
|
||||
while(time > 200)
|
||||
{
|
||||
time -= 100;
|
||||
time -= 200;
|
||||
|
||||
launcher.manager.update("fixed");
|
||||
}
|
||||
|
|
@ -912,7 +989,16 @@ bool snakeLoop()
|
|||
|
||||
launcher.manager.end();
|
||||
|
||||
//snake.drawMap();
|
||||
|
||||
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);
|
||||
if(jobs)Mallocator.dispose(jobs);
|
||||
version(WebAssembly)pthread_key_delete(tls_key);
|
||||
else version(Android)pthread_key_delete(tls_key);
|
||||
}
|
||||
|
||||
version(WebAssembly)
|
||||
{
|
||||
__gshared pthread_key_t tls_key;
|
||||
}
|
||||
else version(Android)
|
||||
{
|
||||
__gshared pthread_key_t tls_key;
|
||||
}
|
||||
else static uint thread_id = 0;
|
||||
|
||||
ThreadPool pool;
|
||||
|
|
@ -105,6 +110,7 @@ struct ECSJobUpdater
|
|||
void onCreate(uint threads_count)
|
||||
{
|
||||
version(WebAssembly)pthread_key_create(&tls_key, null);
|
||||
else version(Android)pthread_key_create(&tls_key, null);
|
||||
|
||||
pool.initialize();
|
||||
thread_data = pool.registerExternalThread();
|
||||
|
|
@ -116,6 +122,7 @@ struct ECSJobUpdater
|
|||
uint getThreadID() @nogc nothrow
|
||||
{
|
||||
version(WebAssembly)return cast(int)pthread_getspecific(tls_key);
|
||||
else version(Android)return cast(int)pthread_getspecific(tls_key);
|
||||
else return thread_id;
|
||||
}
|
||||
|
||||
|
|
@ -200,6 +207,11 @@ struct ECSJobUpdater
|
|||
}
|
||||
else job.execute();
|
||||
}
|
||||
else version(Android)
|
||||
{
|
||||
pthread_setspecific(tls_key, cast(void*)th_data.threadId);
|
||||
job.execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
|
||||
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 bubel.ecs.entity;
|
||||
import bubel.ecs.manager;
|
||||
import bubel.ecs.std;
|
||||
import bubel.ecs.system;
|
||||
import bubel.ecs.vector;
|
||||
import bubel.ecs.entity;
|
||||
|
||||
import ecs_utils.math.vector;
|
||||
|
||||
import gui.attributes;
|
||||
import gui.component;
|
||||
import gui.system;
|
||||
import gui.template_;
|
||||
|
||||
import std.traits;
|
||||
|
||||
extern(C):
|
||||
|
||||
struct GUIManager
|
||||
{
|
||||
Vector!SystemGUI systems;
|
||||
Vector!ComponentGUI components;
|
||||
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()
|
||||
{
|
||||
|
|
@ -27,23 +60,51 @@ struct GUIManager
|
|||
{
|
||||
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();
|
||||
templates.clear();
|
||||
selected_tempalte = 0;
|
||||
components.clear();
|
||||
selected_template = 0;
|
||||
selected_component = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
foreach(ref sys; systems)
|
||||
{
|
||||
if(sys.id == id)return;
|
||||
}
|
||||
System* system = launcher.manager.getSystem(id);
|
||||
//const (char)* name =
|
||||
systems.add(SystemGUI(name,system,enabled));
|
||||
systems.add(SystemGUI(name,id,enabled));
|
||||
}
|
||||
|
||||
void addTemplate(ushort[] components, const (char)* name)
|
||||
|
|
@ -56,43 +117,394 @@ struct GUIManager
|
|||
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()
|
||||
{
|
||||
if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding))
|
||||
if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
bool true_ = true;
|
||||
//bool true_ = true;
|
||||
igIndent(8);
|
||||
foreach(ref SystemGUI system;systems)
|
||||
{
|
||||
if(igCheckbox(system.name,&system.enabled))
|
||||
{
|
||||
if(system.enabled)system.system.enable();
|
||||
else system.system.disable();
|
||||
System* sys = launcher.manager.getSystem(system.id);
|
||||
if(system.enabled)sys.enable();
|
||||
else sys.disable();
|
||||
}
|
||||
}
|
||||
igUnindent(8);
|
||||
}
|
||||
}
|
||||
|
||||
static vec4 colorUintToVec4(uint color)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
case ImGuiDataType_S8:memcpy(v_backup.ptr, v, 1);break;
|
||||
case ImGuiDataType_S16:memcpy(v_backup.ptr, v, 2);break;
|
||||
case ImGuiDataType_S32:memcpy(v_backup.ptr, v, 4);break;
|
||||
case ImGuiDataType_U8:memcpy(v_backup.ptr, v, 1);break;
|
||||
case ImGuiDataType_U16:memcpy(v_backup.ptr, v, 2);break;
|
||||
case ImGuiDataType_U32:memcpy(v_backup.ptr, v, 4);break;
|
||||
case ImGuiDataType_Float:memcpy(v_backup.ptr, v, 4);break;
|
||||
}
|
||||
if (!igDragScalar(label, data_type, v, v_speed, v_min, v_max, format, power))
|
||||
return false;
|
||||
|
||||
final switch(data_type)
|
||||
{
|
||||
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(igBeginCombo("Template",templates[selected_tempalte].name,0))
|
||||
{
|
||||
if(igListBoxHeaderInt("Template",cast(int)templates.length,cast(int)templates.length))
|
||||
{
|
||||
foreach(i, tmpl; templates)
|
||||
{
|
||||
if(igSelectable(tmpl.name,false,0,ImVec2(0,0)))
|
||||
if(igSelectable(tmpl.name,selected_template == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0)))
|
||||
{
|
||||
selected_tempalte = cast(uint)i;
|
||||
selected_template = cast(uint)i;
|
||||
}
|
||||
}
|
||||
igEndCombo();
|
||||
igListBoxFooter();
|
||||
}
|
||||
}
|
||||
else
|
||||
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(igBeginCombo("Template",null,0))igEndCombo();
|
||||
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
|
||||
{
|
||||
const (char)* name;
|
||||
System* system;
|
||||
//System* system;
|
||||
ushort id;
|
||||
|
||||
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"
|
||||
],
|
||||
"dependencies": {
|
||||
"bindbc-sdl":"0.13.0",
|
||||
"bindbc-sdl":"0.19.0",
|
||||
"ecs":{"path":"../../"}
|
||||
},
|
||||
"versions": [
|
||||
"BindSDL_Image",
|
||||
"SDL_2010"
|
||||
],
|
||||
|
||||
"configurations" : [
|
||||
{
|
||||
"name" : "default",
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ module ecs_utils.gfx.buffer;
|
|||
|
||||
import bubel.ecs.std;
|
||||
|
||||
import glad.gl.gl;
|
||||
import glad.gl.gles2;
|
||||
//import glad.gl.gl;
|
||||
//import glad.gl.gles2;
|
||||
|
||||
version(WebAssembly)import glad.gl.gles2;
|
||||
else version(Android)import glad.gl.gles2;
|
||||
else import glad.gl.gl;
|
||||
|
||||
extern(C):
|
||||
|
||||
|
|
@ -64,13 +68,13 @@ struct Buffer
|
|||
void map(BindTarget target) nothrow
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -76,6 +78,25 @@ struct Material
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
|||
|
||||
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;
|
||||
|
||||
extern(C):
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import ecs_utils.math.vector;
|
|||
import bubel.ecs.block_allocator;
|
||||
import bubel.ecs.vector;
|
||||
version(WebAssembly)import glad.gl.gles2;
|
||||
else version(Android)import glad.gl.gles2;
|
||||
else import glad.gl.gl;
|
||||
|
||||
version = ver1;
|
||||
|
|
@ -66,8 +67,10 @@ struct Renderer
|
|||
enum max_items = batch_size;//963;
|
||||
byte[] batch_vertices;
|
||||
ushort[] batch_indices;
|
||||
void* memory;
|
||||
void* memory = null;
|
||||
uint items = 0;
|
||||
uint material_id;
|
||||
uint texture_id;
|
||||
}
|
||||
|
||||
Mutex* get_block_mutex;
|
||||
|
|
@ -127,11 +130,11 @@ struct Renderer
|
|||
block_stack_mutex.unlock();*/
|
||||
foreach(ref Thread thread; threads)
|
||||
{
|
||||
foreach(VertexBlock block; thread.blocks)
|
||||
foreach(VertexBlock block; thread.filled_blocks)
|
||||
{
|
||||
allocator.freeBlock(block.memory);
|
||||
}
|
||||
thread.blocks.clear();
|
||||
thread.filled_blocks.clear();
|
||||
}
|
||||
render_blocks = 0;
|
||||
current_block = 0;
|
||||
|
|
@ -143,13 +146,13 @@ struct Renderer
|
|||
{
|
||||
foreach(ref Thread thread; threads)
|
||||
{
|
||||
foreach(VertexBlock block; thread.blocks)
|
||||
foreach(VertexBlock block; thread.filled_blocks)
|
||||
{
|
||||
uint items = block.items;
|
||||
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_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;
|
||||
}
|
||||
//thread.blocks.clear();
|
||||
|
|
@ -172,17 +175,38 @@ struct Renderer
|
|||
foreach(i, ref Thread thread; threads)
|
||||
{
|
||||
//pushBlock(thread.block);
|
||||
thread.blocks.add(thread.block);
|
||||
thread.block = getBlock();
|
||||
foreach(ref block; thread.blocks)
|
||||
{
|
||||
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
|
||||
{
|
||||
//Vector!VertexBlock block;
|
||||
RenderData[] render_list;
|
||||
VertexBlock block;
|
||||
Vector!VertexBlock blocks;
|
||||
VertexBlock[] blocks;
|
||||
Vector!VertexBlock filled_blocks;
|
||||
}
|
||||
Thread[] threads;
|
||||
|
||||
|
|
@ -224,6 +248,8 @@ struct Renderer
|
|||
|
||||
struct DrawCall
|
||||
{
|
||||
uint texture_id;
|
||||
uint material_id;
|
||||
uint start;
|
||||
uint count;
|
||||
}
|
||||
|
|
@ -248,6 +274,7 @@ struct Renderer
|
|||
|
||||
void initialize()
|
||||
{
|
||||
import ecs_utils.gfx.config;
|
||||
//this.technique = __ecs_used_technique;
|
||||
__initialize(this);
|
||||
|
||||
|
|
@ -260,7 +287,8 @@ struct Renderer
|
|||
threads = Mallocator.makeArray!Thread(32);
|
||||
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;
|
||||
__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_)
|
||||
{
|
||||
|
|
@ -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;
|
||||
with(this_)
|
||||
{
|
||||
//pos += view_pos;
|
||||
size.x *= view_size.x;
|
||||
size.y *= view_size.y;
|
||||
pos.x = pos.x * view_size.x + view_pos.x;
|
||||
pos.y = pos.y * view_size.y + view_pos.y;//*/
|
||||
vec2 pos = void;
|
||||
vec2 size = void;
|
||||
size.x = data.size.x * view_size.x;
|
||||
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;
|
||||
else void* ptr = uniform_block.ptr + data_index;*/
|
||||
if(data_ptr is null)return;
|
||||
void* ptr = data_ptr + data_index;
|
||||
if(angle == 0)
|
||||
if(data.angle == 0)
|
||||
{
|
||||
*cast(float*)ptr = size.x;
|
||||
*cast(float*)(ptr+4) = 0;
|
||||
|
|
@ -467,8 +500,8 @@ struct Renderer
|
|||
else
|
||||
{
|
||||
//import core.stdc.math;
|
||||
float sinn = sinf(angle);
|
||||
float coss = cosf(angle);
|
||||
float sinn = sinf(data.angle);
|
||||
float coss = cosf(data.angle);
|
||||
*cast(float*)ptr = coss * size.x;
|
||||
*cast(float*)(ptr+4) = -sinn * size.y;
|
||||
*cast(float*)(ptr+8) = sinn * size.x;
|
||||
|
|
@ -477,12 +510,12 @@ struct Renderer
|
|||
|
||||
//memcpy(ptr,);
|
||||
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].texture = tex;
|
||||
render_list[item_id].material_id = material_id;
|
||||
render_list[item_id].mesh_id = mesh_id;
|
||||
render_list[item_id].texture = *cast(Texture*)&data.texture;
|
||||
render_list[item_id].material_id = data.material_id;
|
||||
render_list[item_id].mesh_id = data.mesh_id;
|
||||
|
||||
data_index += data_offset;
|
||||
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;
|
||||
short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)];
|
||||
|
||||
//import core.stdc.string;
|
||||
with(this_)
|
||||
{
|
||||
uint thread_id = data.thread_id;
|
||||
//if(item_id >= MaxObjects)return;
|
||||
//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;
|
||||
}
|
||||
|
||||
pos.x = pos.x * view_size.x + view_pos.x;
|
||||
pos.y = pos.y * view_size.y + view_pos.y;//*/
|
||||
short[3] mem = [data.depth, *cast(short*)&data.color, *(cast(short*)&data.color + 1)];
|
||||
|
||||
vec2 pos = void;
|
||||
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;
|
||||
*cast(float*)ptr = size.x;
|
||||
|
|
@ -512,13 +570,16 @@ struct Renderer
|
|||
memcpy(ptr+16,pos.data.ptr,8);
|
||||
memcpy(ptr+32,coords.data.ptr,16);*/
|
||||
|
||||
short[] verts = cast(short[])threads[thread_id].block.batch_vertices;
|
||||
uint item_id = threads[thread_id].block.items;
|
||||
short[] verts = (cast(short*)block.batch_vertices.ptr)[0..block.batch_vertices.length>>1];
|
||||
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.y *= view_size.y;
|
||||
size.x = data.size.x * view_size.x;
|
||||
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+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191);
|
||||
|
|
@ -550,10 +611,11 @@ struct Renderer
|
|||
else
|
||||
{
|
||||
//import core.stdc.math;
|
||||
float sinx = sinf(angle) * size.x * view_size.y;
|
||||
float cosx = cosf(angle) * size.x * view_size.x;
|
||||
float siny = sinf(angle) * size.y * view_size.x;
|
||||
float cosy = cosf(angle) * size.y * view_size.y;
|
||||
float angle = data.angle;
|
||||
float sinx = sinf(angle) * data.size.x * view_size.y;
|
||||
float cosx = cosf(angle) * data.size.x * view_size.x;
|
||||
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+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y;
|
||||
|
|
@ -618,7 +680,7 @@ struct Renderer
|
|||
|
||||
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+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;
|
||||
|
||||
//data_index += 1;//data_offset;
|
||||
threads[thread_id].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();
|
||||
}
|
||||
block.items++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -657,6 +713,7 @@ struct Renderer
|
|||
{
|
||||
glClearColor(0,0,0,0);
|
||||
glViewport(0,0,this_.resolution.x,this_.resolution.y);
|
||||
glDepthMask(1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
|
@ -667,6 +724,10 @@ struct Renderer
|
|||
{
|
||||
glDepthRangef(0,1);
|
||||
}
|
||||
else version(Android)
|
||||
{
|
||||
glDepthRangef(0,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDepthRange(0,1);
|
||||
|
|
@ -822,9 +883,9 @@ struct Renderer
|
|||
//uint items = item_id/batch_size+1;
|
||||
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();
|
||||
float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1];
|
||||
GfxConfig.materials[material_id].pushUniforms(data.ptr);
|
||||
|
|
@ -1054,7 +1115,8 @@ struct Renderer
|
|||
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_) __clear;
|
||||
__gshared void function(ref Renderer this_) __initialize;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import bindbc.sdl;
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -67,10 +69,12 @@ struct Shader
|
|||
}
|
||||
|
||||
version(WebAssembly)const char* glsl = "#version 100\n";
|
||||
else version(Android)const char* glsl = "#version 100\n";
|
||||
else const char* glsl = "#version 330\n";
|
||||
const char* buffer = data.code.ptr;
|
||||
char* ver;
|
||||
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;
|
||||
/*switch(__ecs_used_technique)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ import bubel.ecs.std;
|
|||
|
||||
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):
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ struct Texture
|
|||
data.bpp = 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.size = ivec2(surf.w, surf.h);
|
||||
|
||||
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_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);
|
||||
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);
|
||||
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,data.size.x,data.size.y,0,GL_RGBA,GL_UNSIGNED_BYTE,data.data.ptr);
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +83,7 @@ struct Texture
|
|||
glBindTexture(GL_TEXTURE_2D, data.gl_handle);
|
||||
}
|
||||
|
||||
void destory() @nogc nothrow
|
||||
void destroy() @nogc nothrow
|
||||
{
|
||||
if(data)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ else :
|
|||
|
||||
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;
|
||||
|
||||
|
|
@ -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.
|
||||
// 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);
|
||||
//#else*/
|
||||
if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS)
|
||||
|
|
@ -291,10 +293,11 @@ void ImGuiImplSDL2NewFrame(SDL_Window* window)
|
|||
int w, h;
|
||||
int display_w, display_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);
|
||||
if (w > 0 && h > 0)
|
||||
io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h);
|
||||
// if (w > 0 && h > 0)
|
||||
// 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)
|
||||
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 ImGuiImplOpenGL2Init()
|
||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
{
|
||||
// Setup back-end capabilities flags
|
||||
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;
|
||||
}
|
||||
|
||||
void ImGuiImplOpenGL2Shutdown()
|
||||
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||
{
|
||||
ImGuiImplOpenGL2DestroyDeviceObjects();
|
||||
}
|
||||
|
||||
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.
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
//glDisable(GL_LIGHTING);
|
||||
//glDisable(GL_COLOR_MATERIAL);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
// #ifdef GL_POLYGON_MODE
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
// #endif
|
||||
|
||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||
// 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:
|
||||
// GLint last_program;
|
||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
||||
// glUseProgram(0);
|
||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
||||
// glUseProgram(last_program)
|
||||
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||
bool clip_origin_lower_left = true;
|
||||
// #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
|
||||
// GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
||||
// if (current_clip_origin == GL_UPPER_LEFT)
|
||||
// clip_origin_lower_left = false;
|
||||
// #endif
|
||||
|
||||
// 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.
|
||||
glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
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);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
float L = draw_data.DisplayPos.x;
|
||||
float R = draw_data.DisplayPos.x + draw_data.DisplaySize.x;
|
||||
float T = draw_data.DisplayPos.y;
|
||||
float B = draw_data.DisplayPos.y + draw_data.DisplaySize.y;
|
||||
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
||||
const float[4][4] ortho_projection =
|
||||
[
|
||||
[ 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)
|
||||
// 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)
|
||||
|
||||
void ImGui_ImplOpenGL3_Shutdown()
|
||||
{
|
||||
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)
|
||||
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);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
// 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[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_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
|
||||
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
|
||||
ImVec2 clip_off = draw_data.DisplayPos; // (0,0) unless using multi-viewports
|
||||
|
|
@ -401,23 +775,22 @@ void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data)
|
|||
// Render command lists
|
||||
for (int n = 0; n < draw_data.CmdListsCount; n++)
|
||||
{
|
||||
ImDrawList* cmd_list = draw_data.CmdLists[n];
|
||||
ImDrawVert* vtx_buffer = cmd_list.VtxBuffer.Data;
|
||||
ImDrawIdx* idx_buffer = cmd_list.IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.pos.offsetof));
|
||||
glTexCoordPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.uv.offsetof));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.col.offsetof));
|
||||
const ImDrawList* cmd_list = draw_data.CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
glBufferData(GL_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.VtxBuffer.Size * ImDrawVert.sizeof, cast(const GLvoid*)cmd_list.VtxBuffer.Data, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.IdxBuffer.Size * ImDrawIdx.sizeof, cast(const GLvoid*)cmd_list.IdxBuffer.Data, GL_STREAM_DRAW);
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list.CmdBuffer.Data[cmd_i];
|
||||
if (pcmd.UserCallback)
|
||||
if (pcmd.UserCallback != null)
|
||||
{
|
||||
// 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.)
|
||||
/*if (pcmd.UserCallback == &ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else*/
|
||||
// if (pcmd.UserCallback == ImDrawCallback_ResetRenderState)
|
||||
// ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||
// else
|
||||
pcmd.UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
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));
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, cast(GLuint)pcmd.TextureId);
|
||||
glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
||||
glBindTexture(GL_TEXTURE_2D, cast(GLuint)cast(sizediff_t)pcmd.TextureId);
|
||||
// #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
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glBindTexture(GL_TEXTURE_2D, cast(GLuint)last_texture);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
glPolygonMode(GL_FRONT, cast(GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, cast(GLenum)last_polygon_mode[1]);
|
||||
glUseProgram(last_program);
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
// #ifdef GL_SAMPLER_BINDING
|
||||
// glBindSampler(0, last_sampler);
|
||||
// #endif
|
||||
glActiveTexture(last_active_texture);
|
||||
// #ifndef IMGUI_IMPL_OPENGL_ES2
|
||||
// glBindVertexArray(last_vertex_array_object);
|
||||
// #endif
|
||||
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]);
|
||||
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;
|
||||
|
||||
import ecs_utils.utils;
|
||||
|
||||
struct vec2
|
||||
{
|
||||
this(float v) @nogc nothrow
|
||||
|
|
@ -42,6 +44,11 @@ struct vec2
|
|||
else static assert(0, "Operator "~op~" not implemented");
|
||||
}
|
||||
|
||||
vec2 opUnary(string op)()if (op == "-")
|
||||
{
|
||||
return vec2(-x,-y);
|
||||
}
|
||||
|
||||
ivec2 opCast()
|
||||
{
|
||||
return ivec2(cast(int)x,cast(int)y);
|
||||
|
|
@ -71,6 +78,31 @@ struct vec2
|
|||
}
|
||||
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
|
||||
|
|
|
|||
|
|
@ -2,13 +2,26 @@ module ecs_utils.utils;
|
|||
|
||||
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;
|
||||
return rand() % range - min;
|
||||
}
|
||||
|
||||
float randomf()
|
||||
float randomf() nothrow @nogc @trusted
|
||||
{
|
||||
const float scale = 1.0 / 32_767.0;
|
||||
return cast(float)(rand() & 0x007FFF) * scale;
|
||||
|
|
@ -21,6 +34,38 @@ float randomRangef(float min, float max)
|
|||
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)
|
||||
{
|
||||
public import core.stdc.stdio : printf;
|
||||
|
|
@ -32,9 +77,13 @@ version(GNU)
|
|||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
6
dub.json
6
dub.json
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"name": "ecs",
|
||||
"name": "bubel_ecs",
|
||||
"targetName" : "ecs",
|
||||
"authors": [
|
||||
"Michał Masiukiewicz", "Dawid Masiukiewicz"
|
||||
],
|
||||
|
|
@ -118,7 +119,8 @@
|
|||
"-unittest"
|
||||
],
|
||||
"dflags-gdc": [
|
||||
"-fno-druntime"
|
||||
"-fno-druntime",
|
||||
"-lpthread"
|
||||
],
|
||||
"sourcePaths": ["source/","tests/"],
|
||||
"mainSourceFile":"tests/runner.d",
|
||||
|
|
|
|||
31
meson.build
31
meson.build
|
|
@ -23,6 +23,8 @@ tests_src = [
|
|||
]
|
||||
|
||||
betterC_opt = get_option('betterC')
|
||||
BuildDemos_opt = get_option('BuildDemos')
|
||||
LTO_otp = get_option('LTO')
|
||||
|
||||
comp = meson.get_compiler('d')
|
||||
|
||||
|
|
@ -31,16 +33,43 @@ comp_id = comp.get_id()
|
|||
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 comp_id == 'gcc'
|
||||
args += ['-fno-druntime']
|
||||
link_args += ['-fno-druntime']
|
||||
else
|
||||
args += '-betterC'
|
||||
link_args += '-betterC'
|
||||
endif
|
||||
endif
|
||||
|
||||
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)
|
||||
|
||||
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('BuildDemos', type: 'boolean', value: false)
|
||||
option('LTO', type: 'boolean', value: false)
|
||||
|
|
@ -54,6 +54,7 @@ struct BlockAllocator
|
|||
Mallocator.dispose(pointers);
|
||||
pointers = next_pointers;
|
||||
}
|
||||
next_block = null;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -34,15 +34,26 @@ struct Entity
|
|||
*/
|
||||
T* getComponent(T)() const
|
||||
{
|
||||
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
||||
/*EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
|
||||
EntityManager.EntityInfo* info = block.type_info;
|
||||
if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)
|
||||
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.EntityInfo* info = block.type_info;
|
||||
|
|
@ -50,7 +61,7 @@ struct Entity
|
|||
return true;
|
||||
}
|
||||
|
||||
EntityMeta getMeta()
|
||||
EntityMeta getMeta() const
|
||||
{
|
||||
EntityMeta meta;
|
||||
meta.block = gEM.getMetaData(&this);
|
||||
|
|
@ -66,15 +77,26 @@ struct EntityMeta
|
|||
|
||||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
bool hasComponent(ushort component_id)
|
||||
void* getComponent(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 null;
|
||||
|
||||
return (cast(void*)block + info.deltas[component_id] + index * gEM.components[component_id].size);
|
||||
}
|
||||
|
||||
bool hasComponent(ushort component_id) const
|
||||
{
|
||||
const EntityManager.EntityInfo* info = block.type_info;
|
||||
if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false;
|
||||
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;
|
||||
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.
|
||||
*/
|
||||
pragma(inline, false) EntityID getNewID() nothrow @nogc
|
||||
EntityID getNewID() nothrow @nogc
|
||||
{
|
||||
int current = m_stack_top.atomicOp!"-="(1) + 1;
|
||||
if (current < 0)
|
||||
|
|
@ -177,15 +177,9 @@ struct IDManager
|
|||
if (m_last_id > 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);
|
||||
memcpy(new_stack.ptr, m_free_stack.ptr, m_free_stack.length * uint.sizeof);
|
||||
Mallocator.dispose(m_free_stack);
|
||||
m_free_stack = new_stack;
|
||||
m_ids_array = Mallocator.resizeArray(m_ids_array, begin + (m_blocks_count << 16));
|
||||
m_free_stack = Mallocator.resizeArray(m_free_stack, m_ids_array.length);
|
||||
|
||||
foreach (block; m_blocks[0 .. m_blocks_count - 1])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,29 +96,7 @@ export struct EntityManager
|
|||
{
|
||||
foreach (ref system; systems)
|
||||
{
|
||||
system.disable();
|
||||
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);
|
||||
system.destroy();
|
||||
}
|
||||
|
||||
foreach (EntityInfo* info; &entities_infos.byValue)
|
||||
|
|
@ -382,6 +360,10 @@ export struct EntityManager
|
|||
else
|
||||
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.m_pass = pass;
|
||||
|
||||
|
|
@ -418,9 +400,11 @@ export struct EntityManager
|
|||
static if (Params.length == 2 && is(Params[0] == Entity*))
|
||||
{
|
||||
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);
|
||||
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 ~ "\".");
|
||||
|
||||
callers[i].callback = cast(void*)&callEventHandler!(EventParamType);
|
||||
|
|
@ -456,7 +440,7 @@ export struct EntityManager
|
|||
uint writable_dep = 1;
|
||||
}
|
||||
|
||||
static ComponentsCounts getComponentsCounts()()
|
||||
static ComponentsCounts getComponentsCounts()
|
||||
{
|
||||
ComponentsCounts components_counts;
|
||||
|
||||
|
|
@ -479,7 +463,8 @@ export struct EntityManager
|
|||
string name;
|
||||
static if (isArray!MemberType)
|
||||
{ // 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;
|
||||
|
|
@ -679,7 +664,7 @@ export struct EntityManager
|
|||
|
||||
}
|
||||
|
||||
static ComponentsIndices!component_counts getComponentsInfo()()
|
||||
static ComponentsIndices!component_counts getComponentsInfo()
|
||||
{
|
||||
ComponentsIndices!component_counts components_info;
|
||||
|
||||
|
|
@ -704,7 +689,9 @@ export struct EntityManager
|
|||
string name;
|
||||
static if (isArray!MemberType)
|
||||
{ // 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;
|
||||
|
|
@ -759,7 +746,8 @@ export struct EntityManager
|
|||
{
|
||||
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();
|
||||
|
||||
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))
|
||||
|
|
@ -828,10 +816,10 @@ export struct EntityManager
|
|||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing component.");
|
||||
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 ~ "\".");
|
||||
system.m_components[iii] = comp;
|
||||
}
|
||||
|
|
@ -840,10 +828,10 @@ export struct EntityManager
|
|||
ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing component.");
|
||||
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 ~ "\".");
|
||||
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);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing component.");
|
||||
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 ~ "\".");
|
||||
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);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing component.");
|
||||
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 ~ "\".");
|
||||
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);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing component.");
|
||||
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 ~ "\".");
|
||||
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)
|
||||
{
|
||||
//enum ComponentsIndices components_info = getComponentsInfo();
|
||||
|
|
@ -906,7 +894,9 @@ export struct EntityManager
|
|||
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,
|
||||
Sys.EntitiesData, comp_info.name)))*)(
|
||||
|
|
@ -914,7 +904,8 @@ export struct EntityManager
|
|||
.. 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
|
||||
&& info.deltas[system.m_optional_components[iii]] != 0)
|
||||
|
|
@ -928,7 +919,7 @@ export struct EntityManager
|
|||
}
|
||||
}
|
||||
|
||||
/*bool checkOnUpdateParams()()
|
||||
/*bool checkOnUpdateParams()
|
||||
{
|
||||
bool ret = false;
|
||||
foreach (func; __traits(getOverloads, Sys, "onUpdate"))
|
||||
|
|
@ -1005,15 +996,18 @@ export struct EntityManager
|
|||
else
|
||||
entities_count = block.entities_count;
|
||||
|
||||
if (entities_count > 0)
|
||||
{
|
||||
assert(entities_count <= block.entities_count
|
||||
&& offset <= block.entities_count);
|
||||
&& 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;
|
||||
input_data.thread_id = cast(
|
||||
typeof(input_data.thread_id)) data.thread_id;
|
||||
}
|
||||
|
||||
static if (hasMember!(Sys.EntitiesData, "job_id"))
|
||||
|
|
@ -1023,8 +1017,9 @@ export struct EntityManager
|
|||
|
||||
//s.onUpdate(input_data);
|
||||
(cast(typeof(&__traits(getOverloads, s,
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data);
|
||||
|
||||
"onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(
|
||||
input_data);
|
||||
}
|
||||
block = block.next_block;
|
||||
offset = 0;
|
||||
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!("onDisable")(&system.m_disable);
|
||||
catchFunction!("onCreate")(&system.m_create);
|
||||
|
|
@ -1126,6 +1147,8 @@ export struct EntityManager
|
|||
catchEntityFunction!("onRemoveEntity")(&system.m_remove_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_priority = priority;
|
||||
//(cast(Sys*) system.m_system_pointer).__ecsInitialize();
|
||||
|
|
@ -1148,10 +1171,10 @@ export struct EntityManager
|
|||
ushort.max);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing dependency.");
|
||||
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 ~ "\".");
|
||||
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);
|
||||
version (D_BetterC)
|
||||
assert(comp != ushort.max,
|
||||
"Can't register system \"" ~ Sys.stringof
|
||||
"Can't register system \"" ~ SystemName
|
||||
~ "\" due to non existing dependency.");
|
||||
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 ~ "\".");
|
||||
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)
|
||||
{
|
||||
systems[sys_id].disable();
|
||||
if (systems[sys_id].m_destroy)
|
||||
(cast(void function(void*)) systems[sys_id].m_destroy)(
|
||||
systems[sys_id].m_system_pointer);
|
||||
system.m_name = systems[sys_id].m_name;
|
||||
systems[sys_id].m_name = null;
|
||||
systems[sys_id].destroy();
|
||||
|
||||
if (system.m_create)
|
||||
(cast(void function(void*)) system.m_create)(system.m_system_pointer);
|
||||
|
|
@ -1183,12 +1205,11 @@ export struct EntityManager
|
|||
system.enable();
|
||||
|
||||
system.m_id = sys_id;
|
||||
system.m_name = systems[sys_id].m_name;
|
||||
systems[sys_id] = system;
|
||||
}
|
||||
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);
|
||||
|
||||
|
|
@ -1247,6 +1268,10 @@ export struct EntityManager
|
|||
{
|
||||
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 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);
|
||||
*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)
|
||||
{
|
||||
Comp.component_id = comp_id;
|
||||
if (components[comp_id].init_data)
|
||||
Mallocator.dispose(components[comp_id].init_data);
|
||||
components[comp_id] = info;
|
||||
}
|
||||
else
|
||||
{
|
||||
components.add(info);
|
||||
Comp.component_id = cast(ushort)(components.length - 1);
|
||||
char[] name = Mallocator.makeArray(cast(char[]) Comp.stringof);
|
||||
/*char[] name = Mallocator.makeArray!char(Comp.stringof.length);
|
||||
name[0..$] = Comp.stringof;*/
|
||||
char[] name = Mallocator.makeArray(cast(char[]) ComponentName);
|
||||
components_map.add(name, cast(ushort)(components.length - 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -1323,7 +1348,8 @@ export struct EntityManager
|
|||
info.size = Ev.sizeof;
|
||||
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)
|
||||
{
|
||||
Ev.event_id = event_id;
|
||||
|
|
@ -1332,26 +1358,31 @@ export struct EntityManager
|
|||
{
|
||||
events.add(info);
|
||||
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)
|
||||
{
|
||||
//TODO: check if onUpdate function is good
|
||||
Sys* s;
|
||||
static assert(isDelegate!func, "Function must be delegate.");
|
||||
static assert(__traits(hasMember, Sys, "EntitiesData"),
|
||||
"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"),
|
||||
"Can't call function with system which hasn't onUpdate function callback.");
|
||||
static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
|
||||
functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)),
|
||||
"Function must match system update function.");
|
||||
// static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate),
|
||||
// functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)),
|
||||
// "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.");
|
||||
|
||||
System* system = getSystem(Sys.system_id);
|
||||
assert(system != null,
|
||||
"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)
|
||||
{
|
||||
|
|
@ -1479,21 +1510,28 @@ export struct EntityManager
|
|||
if (first_block is null || blocks_count == 0)
|
||||
continue;
|
||||
|
||||
//if this info will fill job
|
||||
if ((blocks_count - 1) * info.max_entities + entities_count
|
||||
+ info.last_block.entities_count - first_elem >= entities_per_job)
|
||||
{
|
||||
int reamaining_entities = (entities_per_job - entities_count - (
|
||||
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;
|
||||
EntitiesBlock* block = first_block;
|
||||
foreach (i; 0 .. full_blocks_count + 1)
|
||||
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 + (
|
||||
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,
|
||||
info, sys.m_update_delegate, first_block,
|
||||
cast(ushort)(full_blocks_count + 1),
|
||||
|
|
@ -1508,6 +1546,8 @@ export struct EntityManager
|
|||
entities_count += full_blocks_count * info.max_entities + (
|
||||
first_block.entities_count - first_elem); // - first_elem;
|
||||
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,
|
||||
info, sys.m_update_delegate, first_block,
|
||||
cast(ushort)(full_blocks_count + 2),
|
||||
|
|
@ -1515,19 +1555,31 @@ export struct EntityManager
|
|||
tmp_datas.add(data);
|
||||
first_elem = last_elem;
|
||||
blocks_count -= full_blocks_count + 1;
|
||||
assert(first_elem <= block.entities_count);
|
||||
first_block = block;
|
||||
if (last_elem == block.entities_count)
|
||||
{
|
||||
assert(block.next_block == null);
|
||||
first_block = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint last_elem = entities_per_job - entities_count;
|
||||
assert(last_elem > 0);
|
||||
CallData data = CallData(caller.system_id, sys,
|
||||
info, sys.m_update_delegate, first_block, 1,
|
||||
cast(ushort) first_elem, cast(ushort)(first_elem + last_elem));
|
||||
tmp_datas.add(data);
|
||||
first_elem += last_elem;
|
||||
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();
|
||||
entities_count = 0;
|
||||
|
|
@ -1535,6 +1587,7 @@ export struct EntityManager
|
|||
}
|
||||
else
|
||||
{
|
||||
//take whole info blocks
|
||||
CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate,
|
||||
first_block, cast(ushort) blocks_count, cast(ushort) first_elem);
|
||||
tmp_datas.add(data);
|
||||
|
|
@ -1828,6 +1881,8 @@ export struct EntityManager
|
|||
|
||||
foreach (i, id; ids)
|
||||
{
|
||||
if (current_delta == 0)
|
||||
current_delta = ushort.max;
|
||||
alignNum(current_delta, components[id].alignment);
|
||||
info.deltas[id] = cast(ushort) current_delta;
|
||||
current_delta += entites_in_block * components[id].size;
|
||||
|
|
@ -2008,6 +2063,9 @@ export struct EntityManager
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -2050,30 +2108,8 @@ export struct EntityManager
|
|||
{
|
||||
System* system = &systems[system_id];
|
||||
|
||||
if (system.m_excluded_components)
|
||||
{
|
||||
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;
|
||||
connectListenerToEntityInfo(info, system_id);
|
||||
if(!info.systems[system_id])return;
|
||||
|
||||
uint index = 0;
|
||||
for (; index < passes[system.m_pass].system_callers.length; index++)
|
||||
|
|
@ -2486,17 +2522,17 @@ export struct EntityManager
|
|||
{
|
||||
ushort size = components[comp].size;
|
||||
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);
|
||||
|
||||
if (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);
|
||||
|
||||
Entity* new_entity = cast(Entity*) start;
|
||||
|
|
@ -2515,43 +2551,6 @@ export struct EntityManager
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -3100,12 +3099,12 @@ export struct EntityManager
|
|||
swapData();
|
||||
|
||||
has_work = false;
|
||||
// has_work |= updateBlocks();
|
||||
has_work |= updateBlocks();
|
||||
// has_work |= changeEntities();
|
||||
// has_work |= removeEntities();
|
||||
has_work |= updateEvents();
|
||||
|
||||
//id_manager.optimize();
|
||||
id_manager.optimize();
|
||||
has_work |= updateBlocks();
|
||||
has_work |= changeEntities();
|
||||
has_work |= removeEntities();
|
||||
|
|
@ -3493,6 +3492,12 @@ export struct EntityManager
|
|||
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
|
||||
{
|
||||
if (components)
|
||||
|
|
@ -3501,6 +3506,10 @@ export struct EntityManager
|
|||
Mallocator.dispose(deltas);
|
||||
if (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)
|
||||
Mallocator.dispose(systems);
|
||||
if (add_listeners)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,12 @@ struct SimpleVector
|
|||
|
||||
@disable this(this);
|
||||
|
||||
~this() nothrow @nogc
|
||||
{
|
||||
if(data)
|
||||
Mallocator.dispose(data);
|
||||
}
|
||||
|
||||
///Add element to vector
|
||||
void add(ubyte el) nothrow @nogc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ else version (D_BetterC)
|
|||
{
|
||||
private const uint max_alloca = 10000;
|
||||
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
|
||||
{
|
||||
if (alloca_pos + length > max_alloca)
|
||||
|
|
@ -152,13 +152,86 @@ else
|
|||
|
||||
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
|
||||
{
|
||||
T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length];
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -206,7 +279,7 @@ static struct Mallocator
|
|||
|
||||
static if (__traits(isPOD, T))
|
||||
{
|
||||
static immutable T init = T.init;
|
||||
__gshared immutable T init = T.init;
|
||||
memcpy(ret, &init, T.sizeof);
|
||||
}
|
||||
else static if (is(T == struct))
|
||||
|
|
@ -228,7 +301,27 @@ static struct Mallocator
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void dispose(T)(T object) nothrow @nogc
|
||||
static void dispose(T)(T object)
|
||||
{
|
||||
static if (isArray!T)
|
||||
{
|
||||
alias TT = PointerTarget!(typeof(object.ptr));
|
||||
static if (!isPointer!TT)
|
||||
{
|
||||
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();
|
||||
|
|
@ -236,6 +329,7 @@ static struct Mallocator
|
|||
object.__dtor();
|
||||
free(cast(void*) object);
|
||||
}
|
||||
}
|
||||
|
||||
static void alignDispose(T)(T object)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -91,6 +91,38 @@ struct System
|
|||
|
||||
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
|
||||
{
|
||||
ushort id;
|
||||
|
|
@ -162,6 +194,8 @@ package:
|
|||
void* m_remove_entity;
|
||||
void* m_change_entity;
|
||||
|
||||
void* m_filter_entity;
|
||||
|
||||
//void function(ref EntityManager.CallData data) m_initialize;
|
||||
//void function(ref EntityManager.CallData data) m_deinitilize;
|
||||
void* m_initialize;
|
||||
|
|
|
|||
|
|
@ -37,3 +37,35 @@ static long getIndexOfTypeInEntitiesData(EntitiesData, Type)()
|
|||
}
|
||||
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);
|
||||
}
|
||||
158
tests/basic.d
158
tests/basic.d
|
|
@ -139,6 +139,7 @@ void afterEveryTest()
|
|||
unittest
|
||||
{
|
||||
EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray);
|
||||
scope(exit)gEM.freeTemplate(tmpl_);
|
||||
Entity* entity = gEM.addEntity(tmpl_);
|
||||
EntityMeta meta = entity.getMeta();
|
||||
assert(meta.hasComponent(CInt.component_id));
|
||||
|
|
@ -157,6 +158,7 @@ unittest
|
|||
unittest
|
||||
{
|
||||
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.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof));
|
||||
assert(tmpl_.getComponent!CInt);
|
||||
|
|
@ -345,6 +347,7 @@ unittest
|
|||
assert(*tmpl_7.getComponent!CLong == 10);
|
||||
|
||||
gEM.freeTemplate(tmpl_d);
|
||||
gEM.freeTemplate(tmpl_cp);
|
||||
gEM.freeTemplate(tmpl_);
|
||||
gEM.freeTemplate(tmpl_2);
|
||||
gEM.freeTemplate(tmpl_3);
|
||||
|
|
@ -368,6 +371,8 @@ unittest
|
|||
assert(*tmpl_.getComponent!CInt == 1);
|
||||
assert(*tmpl_.getComponent!CFloat == 2.0);
|
||||
assert(tmpl_.info == tmpl_2.info);
|
||||
gEM.freeTemplate(tmpl_);
|
||||
gEM.freeTemplate(tmpl_2);
|
||||
}
|
||||
|
||||
@("MultiRegister")
|
||||
|
|
@ -401,7 +406,7 @@ unittest
|
|||
System* ecs_system = gEM.getSystem(EmptySystem.system_id);
|
||||
assert(ecs_system !is null);
|
||||
assert(ecs_system.id == EmptySystem.system_id);
|
||||
assert(ecs_system.name == "EmptySystem");
|
||||
assert(ecs_system.name == "tests.basic.EmptySystem");
|
||||
|
||||
gEM.begin();
|
||||
|
||||
|
|
@ -605,7 +610,7 @@ unittest
|
|||
assert(ecs_system !is null);
|
||||
assert(ecs_system.id == LongAddSystem.system_id);
|
||||
assert(ecs_system.priority == -1);
|
||||
assert(ecs_system.name == "LongAddSystem");
|
||||
assert(ecs_system.name == "tests.basic.LongAddSystem");
|
||||
|
||||
ushort[1] ids = [CLong.component_id];
|
||||
EntityTemplate* tmpl = gEM.allocateTemplate(ids);
|
||||
|
|
@ -897,7 +902,7 @@ unittest
|
|||
{
|
||||
struct TestSystem
|
||||
{
|
||||
mixin ECS.System;
|
||||
mixin ECS.System!64;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
|
|
@ -1003,15 +1008,51 @@ unittest
|
|||
assert(empty_system.update == 3);
|
||||
system.entities = 0;
|
||||
|
||||
foreach(i;0..10000)gEM.addEntity(tmpl);
|
||||
// foreach(i;0..10000)gEM.addEntity(tmpl);
|
||||
|
||||
// gEM.begin();
|
||||
|
||||
// gEM.updateMT("custom");
|
||||
|
||||
// gEM.end();
|
||||
|
||||
// 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 == 12001);
|
||||
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
|
||||
|
|
@ -1580,3 +1621,106 @@ unittest
|
|||
assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.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
|
||||
{
|
||||
import core.exception : AssertError;
|
||||
import core.exception : AssertError, RangeError;
|
||||
try
|
||||
{
|
||||
unittest_();
|
||||
|
|
@ -249,6 +249,13 @@ struct TestRunner(Args...)
|
|||
test.file_line = cast(int)error.line;
|
||||
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)
|
||||
|
|
|
|||
112
tests/tests.d
112
tests/tests.d
|
|
@ -93,6 +93,13 @@ struct TestEvent2
|
|||
float a;
|
||||
}
|
||||
|
||||
static struct CPosition
|
||||
{
|
||||
mixin ECS.Component;
|
||||
float x;
|
||||
float y;
|
||||
}
|
||||
|
||||
static struct TestComp
|
||||
{
|
||||
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
|
||||
{
|
||||
mixin ECS.System!16; //__gshared ushort system_id;
|
||||
|
|
@ -648,6 +701,7 @@ else:
|
|||
gEM.registerComponent!TestComp;
|
||||
gEM.registerComponent!TestComp3;
|
||||
gEM.registerComponent!TestComp5;
|
||||
gEM.registerComponent!CPosition;
|
||||
|
||||
gEM.registerEvent!TestEvent;
|
||||
gEM.registerEvent!TestEvent2;
|
||||
|
|
@ -669,6 +723,7 @@ else:
|
|||
gEM.registerSystem!EmptySystem(2);
|
||||
gEM.registerSystem!EmptyEventSystem(2);
|
||||
gEM.registerSystem!EventSystem(2);
|
||||
gEM.registerSystem!EverySystem(0);
|
||||
//gEM.registerSystem!TestSystemWithHighPriority(100);
|
||||
//gEM.registerSystem!TestSystem2(0);
|
||||
gEM.endRegister();
|
||||
|
|
@ -693,6 +748,62 @@ else:
|
|||
//dur = (MonoTime.currTime - time).total!"usecs";
|
||||
//writeln("Template allocating: ", dur, " usecs");
|
||||
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();
|
||||
|
||||
EntityID entity;
|
||||
|
|
@ -903,6 +1014,7 @@ else:
|
|||
writeEntityComponents(gEM.getEntity(entity));
|
||||
//import std.stdio;
|
||||
////writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
||||
gEM.freeTemplate(tmpl_empty);
|
||||
gEM.freeTemplate(tmpl);
|
||||
gEM.freeTemplate(tmpl2);
|
||||
gEM.freeTemplate(copy_tempalte);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue