module ecs_utils.gfx.shader; import bindbc.sdl; import ecs.std; import glad.gl.gl; //version = ver1; struct Shader { void create() nothrow { data = Mallocator.make!Data; } bool load(const char[] path) nothrow { if(data is null)data = Mallocator.make!Data; char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; cpath[0..$-1] = path[0..$]; cpath[$-1] = 0; int ind = cast(int)path.length - 1; for(;ind>0;ind--) { if(path[ind] == '.')break; } if(ind < 0)return false; ind++; if(ind + 2 > path.length)return false; char[2] ext = path[ind .. ind + 2]; if(ext[0] == 'v' && ext[1] == 'p')data.type = Type.vertex; else if(ext[0] == 'f' && ext[1] == 'p')data.type = Type.fragment; else return false; SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r");//SDL_LoadFile(cpath.ptr,); if(file) { size_t size = cast(size_t)SDL_RWsize(file); data.code = Mallocator.makeArray!char(size+1); data.code[$-1] = 0; SDL_RWread(file,data.code.ptr,size,1); SDL_RWclose(file); return true; } else return false; } bool compile() nothrow { switch(data.type) { case Type.vertex: data.gl_handle = glCreateShader(GL_VERTEX_SHADER); break; case Type.fragment: data.gl_handle = glCreateShader(GL_FRAGMENT_SHADER); break; default: return false; } version(WebAssembly)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 ver = cast(char*)"#define ver1 1\n".ptr; /*switch(__ecs_used_technique) { case RenderTechnique.simple: ver = cast(char*)"#define ver1 1\n".ptr; break; case RenderTechnique.simple_array: ver = cast(char*)"#define ver2 1\n".ptr; break; case RenderTechnique.vbo_batch: ver = cast(char*)"#define ver10 1\n".ptr; break; case RenderTechnique.instanced_attrib_divisor: ver = cast(char*)"#define ver8 1\n".ptr; break; case RenderTechnique.uniform_buffer: ver = cast(char*)"#define ver3 1\n".ptr; break; case RenderTechnique.uniform_buffer_indexed: ver = cast(char*)"#define ver4 1\n".ptr; break; case RenderTechnique.uniform_buffer_multi_draw: goto case(RenderTechnique.uniform_buffer_multi_draw_indirect); case RenderTechnique.uniform_buffer_instanced: ver = cast(char*)"#define ver5 1\n".ptr; break; case RenderTechnique.uniform_buffer_instanced_mapped_gl2: goto case(RenderTechnique.uniform_buffer_instanced); case RenderTechnique.uniform_buffer_instanced_mapped: goto case(RenderTechnique.uniform_buffer_instanced); case RenderTechnique.uniform_buffer_instanced_persistent_mapped: goto case(RenderTechnique.uniform_buffer_instanced); case RenderTechnique.uniform_buffer_instanced_persistent_mapped_coherent: goto case(RenderTechnique.uniform_buffer_instanced); case RenderTechnique.ssbo_instanced: ver = cast(char*)"#define ver6 1\n".ptr; break; case RenderTechnique.uniform_buffer_draw_indirect: goto case(RenderTechnique.uniform_buffer); case RenderTechnique.uniform_buffer_multi_draw_indirect: ver = cast(char*)"#define ver9 1\n".ptr; break; case RenderTechnique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: ver = cast(char*)"#define ver7 1\n".ptr; break; default:break; }*/ /*version(ver1)const char* ver = "#define ver1 1\n"; version(ver2)const char* ver = "#define ver2 1\n"; version(ver3)const char* ver = "#define ver3 1\n"; version(ver4)const char* ver = "#define ver4 1\n"; version(ver5)const char* ver = "#define ver5 1\n"; version(ver6)const char* ver = "#define ver5 1\n";*/ const char*[3] input = [glsl,ver,buffer]; glShaderSource(data.gl_handle,3,input.ptr,null); glCompileShader(data.gl_handle); int compile; glGetShaderiv(data.gl_handle,GL_COMPILE_STATUS,&compile); if(compile == GL_FALSE) { SDL_Log("Shader compile error! %u %s",data.type,glsl); char[256] log; int log_len; glGetShaderInfoLog(data.gl_handle, 256, &log_len, log.ptr); import ecs_utils.utils; if(log_len)printf("%s",log.ptr); return false; } return true; } void destroy() nothrow { if(data) { if(data.gl_handle)glDeleteShader(data.gl_handle); Mallocator.dispose(data); data = null; } } enum Type { vertex, fragment, geometry } struct Data { char[] code; Type type; uint gl_handle; } Data* data; }