bubel-ecs/demos/utils/source/ecs_utils/gfx/material.d
Mergul 66860b9042 Android update and small improvements
-fixed code do cross compiling to android
-fixed build with GCC (workaround)
-added little benchmark
-several small fixes
-updated meson build (demos building, working with GCC, LDC and DMD)
-added some meson options
-added ImGUI bind for OpenGL3
2020-06-01 11:24:50 +02:00

200 lines
No EOL
4.4 KiB
D

module ecs_utils.gfx.material;
import bindbc.sdl;
import bubel.ecs.std;
import ecs_utils.gfx.shader;
version(WebAssembly)import glad.gl.gles2;
else version(Android)import glad.gl.gles2;
else import glad.gl.gl;
//import mutils.serializer.json;
struct Material
{
void create() nothrow
{
data = Mallocator.make!Data;
}
bool load(const char[] path) nothrow
{
struct LoadData
{
@("malloc") string blend_mode;
@("malloc") string vertex;
@("malloc") string fragment;
void dispose() nothrow
{
//if(blend_mode)Mallocator.instance.dispose(cast(char[])blend_mode);
//if(vertex)Mallocator.instance.dispose(cast(char[])vertex);
//if(fragment)Mallocator.instance.dispose(cast(char[])fragment);
}
}
char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1];
cpath[0..$-1] = path[0..$];
cpath[$-1] = 0;
SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r");
if(file)
{
size_t size = cast(size_t)SDL_RWsize(file);
char[] buffer = Mallocator.makeArray!char(size);
SDL_RWread(file,buffer.ptr,size,1);
LoadData load_data;
scope(exit)load_data.dispose();
/*JSONSerializer serializer = Mallocator.make!JSONSerializer;
scope(exit)Mallocator.dispose(serializer);
serializer.serialize!(Load.yes, true)(load_data,buffer);*/
//if(__ecs_used_backend == Backend.opengl)
{
Shader vsh;
vsh.load(load_data.vertex);
vsh.compile();
Shader fsh;
fsh.load(load_data.fragment);
fsh.compile();
Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)];
attachModules(modules);
}
SDL_RWclose(file);
load_data.dispose();
return true;
}
else return false;
}
void bind() nothrow
{
glUseProgram(data.modules[0].gl_handle);
}
enum BlendMode
{
opaque,
additive,
mixed
}
enum TransformMode
{
position,
matrix
}
struct ShaderModule
{
Shader fragment_shader;
Shader vertex_shader;
uint gl_handle;
}
void attachModules(scope ShaderModule[] modules) nothrow
{
data.modules = Mallocator.makeArray(modules);
}
bool compile() nothrow
{
foreach(ref module_;data.modules)
{
module_.gl_handle = glCreateProgram();
glAttachShader(module_.gl_handle, module_.vertex_shader.data.gl_handle);
glAttachShader(module_.gl_handle, module_.fragment_shader.data.gl_handle);
}
return true;
}
void bindAttribLocation(const char* name, uint location) nothrow
{
foreach(ref module_;data.modules)
{
glBindAttribLocation(module_.gl_handle, location, name);
}
}
bool link() nothrow
{
foreach(ref module_;data.modules)
{
glLinkProgram(module_.gl_handle);
GLint ok = 0;
glGetProgramiv(module_.gl_handle, GL_LINK_STATUS, &ok);
if(!ok)
{
SDL_Log("Program link error!");
return false;
}
}
return true;
}
int getLocation(const char* name)
{
foreach(ref module_;data.modules)
{
int location = glGetUniformLocation(module_.gl_handle,name);
if(location != -1)return location;
}
return -1;
}
void pushBindings()
{
foreach(i;0..data.bindings.length)
{
glUniform1i(data.bindings[i],cast(int)i);
}
}
void pushUniforms(void* ptr)
{
foreach(ref Uniform uniform; data.uniforms)
{
void* local_ptr = ptr + uniform.offset;
glUniform4fv(uniform.location,1,cast(float*)local_ptr);
}
}
enum Type
{
float_,
float4
}
struct Uniform
{
Type type;
int location;
uint offset;
}
struct Data
{
BlendMode blend_mode = BlendMode.opaque;
ShaderModule[] modules;
TransformMode mode;
Uniform[] uniforms;
int[] bindings;
}
Data* data;
}