1 module ecs_utils.gfx.shader; 2 3 import bindbc.sdl; 4 5 import bubel.ecs.std; 6 7 version(WebAssembly)import glad.gl.gles2; 8 else version(Android)import glad.gl.gles2; 9 else import glad.gl.gl; 10 11 //version = ver1; 12 13 struct Shader 14 { 15 16 void create() nothrow 17 { 18 data = Mallocator.make!Data; 19 } 20 21 bool load(const char[] path) nothrow 22 { 23 if(data is null)data = Mallocator.make!Data; 24 25 char[] cpath = (cast(char*)alloca(path.length+1))[0..path.length+1]; 26 cpath[0..$-1] = path[0..$]; 27 cpath[$-1] = 0; 28 29 int ind = cast(int)path.length - 1; 30 for(;ind>0;ind--) 31 { 32 if(path[ind] == '.')break; 33 } 34 if(ind < 0)return false; 35 ind++; 36 if(ind + 2 > path.length)return false; 37 38 char[2] ext = path[ind .. ind + 2]; 39 if(ext[0] == 'v' && ext[1] == 'p')data.type = Type.vertex; 40 else if(ext[0] == 'f' && ext[1] == 'p')data.type = Type.fragment; 41 else return false; 42 43 SDL_RWops* file = SDL_RWFromFile(cpath.ptr,"r");//SDL_LoadFile(cpath.ptr,); 44 if(file) 45 { 46 size_t size = cast(size_t)SDL_RWsize(file); 47 data.code = Mallocator.makeArray!char(size+1); 48 data.code[$-1] = 0; 49 SDL_RWread(file,data.code.ptr,size,1); 50 51 SDL_RWclose(file); 52 return true; 53 } 54 else return false; 55 56 } 57 58 bool compile() nothrow 59 { 60 switch(data.type) 61 { 62 case Type.vertex: 63 data.gl_handle = glCreateShader(GL_VERTEX_SHADER); 64 break; 65 case Type.fragment: 66 data.gl_handle = glCreateShader(GL_FRAGMENT_SHADER); 67 break; 68 default: return false; 69 } 70 71 version(WebAssembly)const char* glsl = "#version 100\n"; 72 else version(Android)const char* glsl = "#version 100\n"; 73 else const char* glsl = "#version 120\n"; 74 const char* buffer = data.code.ptr; 75 char* ver; 76 version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; 77 else version(Android)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; 78 else ver = cast(char*)"#define ver1 1\n".ptr; 79 /*switch(__ecs_used_technique) 80 { 81 case RenderTechnique.simple: 82 ver = cast(char*)"#define ver1 1\n".ptr; 83 break; 84 case RenderTechnique.simple_array: 85 ver = cast(char*)"#define ver2 1\n".ptr; 86 break; 87 case RenderTechnique.vbo_batch: 88 ver = cast(char*)"#define ver10 1\n".ptr; 89 break; 90 case RenderTechnique.instanced_attrib_divisor: 91 ver = cast(char*)"#define ver8 1\n".ptr; 92 break; 93 case RenderTechnique.uniform_buffer: 94 ver = cast(char*)"#define ver3 1\n".ptr; 95 break; 96 case RenderTechnique.uniform_buffer_indexed: 97 ver = cast(char*)"#define ver4 1\n".ptr; 98 break; 99 case RenderTechnique.uniform_buffer_multi_draw: 100 goto case(RenderTechnique.uniform_buffer_multi_draw_indirect); 101 case RenderTechnique.uniform_buffer_instanced: 102 ver = cast(char*)"#define ver5 1\n".ptr; 103 break; 104 case RenderTechnique.uniform_buffer_instanced_mapped_gl2: 105 goto case(RenderTechnique.uniform_buffer_instanced); 106 case RenderTechnique.uniform_buffer_instanced_mapped: 107 goto case(RenderTechnique.uniform_buffer_instanced); 108 case RenderTechnique.uniform_buffer_instanced_persistent_mapped: 109 goto case(RenderTechnique.uniform_buffer_instanced); 110 case RenderTechnique.uniform_buffer_instanced_persistent_mapped_coherent: 111 goto case(RenderTechnique.uniform_buffer_instanced); 112 case RenderTechnique.ssbo_instanced: 113 ver = cast(char*)"#define ver6 1\n".ptr; 114 break; 115 case RenderTechnique.uniform_buffer_draw_indirect: 116 goto case(RenderTechnique.uniform_buffer); 117 case RenderTechnique.uniform_buffer_multi_draw_indirect: 118 ver = cast(char*)"#define ver9 1\n".ptr; 119 break; 120 case RenderTechnique.uniform_buffer_multi_draw_indirect_arb_draw_parameters: 121 ver = cast(char*)"#define ver7 1\n".ptr; 122 break; 123 default:break; 124 }*/ 125 /*version(ver1)const char* ver = "#define ver1 1\n"; 126 version(ver2)const char* ver = "#define ver2 1\n"; 127 version(ver3)const char* ver = "#define ver3 1\n"; 128 version(ver4)const char* ver = "#define ver4 1\n"; 129 version(ver5)const char* ver = "#define ver5 1\n"; 130 version(ver6)const char* ver = "#define ver5 1\n";*/ 131 132 const char*[3] input = [glsl,ver,buffer]; 133 134 glShaderSource(data.gl_handle,3,input.ptr,null); 135 136 glCompileShader(data.gl_handle); 137 138 int compile; 139 glGetShaderiv(data.gl_handle,GL_COMPILE_STATUS,&compile); 140 if(compile == GL_FALSE) 141 { 142 SDL_Log("Shader compile error! %u %s",data.type,glsl); 143 char[256] log; 144 int log_len; 145 glGetShaderInfoLog(data.gl_handle, 256, &log_len, log.ptr); 146 import ecs_utils.utils; 147 if(log_len)printf("%s",log.ptr); 148 return false; 149 } 150 151 return true; 152 } 153 154 void destroy() nothrow 155 { 156 if(data) 157 { 158 if(data.gl_handle)glDeleteShader(data.gl_handle); 159 Mallocator.dispose(data); 160 data = null; 161 } 162 } 163 164 enum Type 165 { 166 vertex, 167 fragment, 168 geometry 169 } 170 171 struct Data 172 { 173 char[] code; 174 Type type; 175 176 uint gl_handle; 177 } 178 179 Data* data; 180 }