Huge demos update

-moved C stdlib function definitions to ecs_utils.utils
-added function to calculate mix(linear interpolation) and rsqrt(fast inverse sqrt)
-added some math to vec2 (length, normalize...)
-improved renderer with possibility to use multiple materials (one per block, not perfect solution for parallel compute, but works with some requirements)
-added blending support for material (opaque, additive, mixed)
-added Android support
-added gprahical representation for mouse tools (tool_circle.d)
-added initial support for editing template components variables
-better Component and Templates listing
-added possibility to add/removes components using mouse
-move CLocation to game_core.basic and reuse in every test
-moved tools code from demos to App (now code is fully separated from demos!)
-some improvement and fixes in Snake demo, with additional systems to handle adding and removing entities
-added new demo: Particles. By now demo has several particles to spawn and support for attractors and vortexes (calculation is made as every attractor with every entity)
-fixed bug with window hover and tools
-improved tool behaviour
-added new material
-now window is always opened as maximized windowed mode
-some minor fixes and improvements
This commit is contained in:
Mergul 2020-06-06 22:46:29 +02:00
parent 13e6ed8fd5
commit e76c5ccdb2
20 changed files with 1804 additions and 288 deletions

View file

@ -68,7 +68,7 @@ struct Buffer
void map(BindTarget target) nothrow
{
bind(target);
version(Android){}else 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

View file

@ -78,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);
}

View file

@ -67,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;
@ -128,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;
@ -144,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();
@ -173,8 +175,15 @@ 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();
}
}
@ -182,8 +191,8 @@ struct Renderer
{
//Vector!VertexBlock block;
RenderData[] render_list;
VertexBlock block;
Vector!VertexBlock blocks;
VertexBlock[] blocks;
Vector!VertexBlock filled_blocks;
}
Thread[] threads;
@ -225,6 +234,8 @@ struct Renderer
struct DrawCall
{
uint texture_id;
uint material_id;
uint start;
uint count;
}
@ -249,6 +260,7 @@ struct Renderer
void initialize()
{
import ecs_utils.gfx.config;
//this.technique = __ecs_used_technique;
__initialize(this);
@ -261,7 +273,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);
}
}
@ -494,12 +507,33 @@ 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)
{
import ecs_utils.gfx.config;
short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)];
//import core.stdc.string;
with(this_)
{
//if(item_id >= MaxObjects)return;
//pos += view_pos;
Thread* thread = &threads[thread_id];
VertexBlock* block;
assert(thread.blocks.length > material_id);
block = &thread.blocks[material_id];
if(block.items == 0)
{
thread.blocks[material_id] = getBlock();
block = &thread.blocks[material_id];
block.material_id = material_id;
}
else if(block.items >= VertexBlock.max_items)
{
//pushBlock(thread.block);
prepared_items += block.items;
thread.filled_blocks.add(*block);
thread.blocks[material_id] = getBlock();
block = &thread.blocks[material_id];
block.material_id = material_id;
}
short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)];
pos.x = pos.x * view_size.x + view_pos.x;
pos.y = pos.y * view_size.y + view_pos.y;//*/
@ -513,8 +547,8 @@ 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;
uint item_id = block.items;
if(angle == 0)
{
@ -619,7 +653,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);
@ -634,14 +668,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);
prepared_items += threads[thread_id].block.items;
threads[thread_id].blocks.add(threads[thread_id].block);
threads[thread_id].block = getBlock();
}
block.items++;
}
}
@ -659,6 +686,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);
@ -828,9 +856,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);

View file

@ -1,5 +1,7 @@
module ecs_utils.math.vector;
import ecs_utils.utils;
struct vec2
{
this(float v) @nogc nothrow
@ -71,6 +73,26 @@ 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();
}
}
struct vec4

View file

@ -2,13 +2,24 @@ 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;
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 +32,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;
@ -34,7 +77,7 @@ else
extern(C) int printf(scope const char* format, ...) @nogc nothrow @system;
public import std.array : staticArray;
}
extern(C) int rand();
extern(C) int rand() nothrow @nogc @trusted;
version(D_BetterC)
{