| 69 | } |
| 70 | |
| 71 | string ParseMaterialFile(string_view mbuf) { |
| 72 | auto p = mbuf; |
| 73 | string err; |
| 74 | string_view last; |
| 75 | string defines; |
| 76 | string vfunctions, pfunctions, cfunctions, vertex, pixel, compute, vdecl, pdecl, csdecl, shader; |
| 77 | string *accum = nullptr; |
| 78 | auto word = [&]() { |
| 79 | p.remove_prefix(min(p.find_first_not_of(" \t\r"), p.size())); |
| 80 | size_t len = min(p.find_first_of(" \t\r"), p.size()); |
| 81 | last = p.substr(0, len); |
| 82 | p.remove_prefix(len); |
| 83 | }; |
| 84 | auto finish = [&]() -> bool { |
| 85 | if (!shader.empty()) { |
| 86 | auto sh = new Shader(); |
| 87 | if (compute.length()) { |
| 88 | #ifdef PLATFORM_WINNIX |
| 89 | extern string glslversion; |
| 90 | auto header = "#version " + glslversion + "\n" + defines; |
| 91 | #else |
| 92 | auto header = "#version 430\n" + defines; |
| 93 | #endif |
| 94 | err = sh->Compile(shader.c_str(), (header + csdecl + cfunctions + |
| 95 | "void main()\n{\n" + compute + "}\n").c_str()); |
| 96 | } else { |
| 97 | string header; |
| 98 | #ifdef PLATFORM_ES3 |
| 99 | #ifdef __EMSCRIPTEN__ |
| 100 | header += "#version 300 es\n"; |
| 101 | #endif |
| 102 | header += "#ifdef GL_ES\nprecision highp float;\n#endif\n"; |
| 103 | #else |
| 104 | #ifdef __APPLE__ |
| 105 | auto supported = glGetString(GL_SHADING_LANGUAGE_VERSION); |
| 106 | // Apple randomly changes what it supports, so just ask for that. |
| 107 | header += string_view("#version ") + string_view((const char *)supported, 1) + |
| 108 | string_view((const char *)supported + 2, 2) + "\n"; |
| 109 | #else |
| 110 | extern string glslversion; |
| 111 | header += "#version " + glslversion + "\n"; |
| 112 | header += "#extension GL_EXT_gpu_shader4 : enable\n"; |
| 113 | #endif |
| 114 | #endif |
| 115 | header += defines; |
| 116 | pdecl = "out vec4 frag_color;\n" + pdecl; |
| 117 | err = sh->Compile(shader.c_str(), |
| 118 | (header + vdecl + vfunctions + "void main()\n{\n" + vertex + |
| 119 | "}\n").c_str(), |
| 120 | (header + pdecl + pfunctions + "void main()\n{\n" + pixel + |
| 121 | "}\n").c_str()); |
| 122 | } |
| 123 | if (!err.empty()) |
| 124 | return true; |
| 125 | shadermap[shader] = sh; |
| 126 | shader.clear(); |
| 127 | } |
| 128 | return false; |