| 215 | } |
| 216 | |
| 217 | void OpenGlRenderer::loadEffectConfig(String const& name, Json const& effectConfig, StringMap<String> const& shaders) { |
| 218 | if (auto effect = m_effects.ptr(name)) { |
| 219 | Logger::info("Reloading OpenGL effect {}", name); |
| 220 | glDeleteProgram(effect->program); |
| 221 | m_effects.erase(name); |
| 222 | } |
| 223 | |
| 224 | GLint status = 0; |
| 225 | char logBuffer[1024]; |
| 226 | |
| 227 | auto compileShader = [&](GLenum type, String const& name) -> GLuint { |
| 228 | GLuint shader = glCreateShader(type); |
| 229 | auto* source = shaders.ptr(name); |
| 230 | if (!source) |
| 231 | return 0; |
| 232 | char const* sourcePtr = source->utf8Ptr(); |
| 233 | glShaderSource(shader, 1, &sourcePtr, NULL); |
| 234 | glCompileShader(shader); |
| 235 | |
| 236 | glGetShaderiv(shader, GL_COMPILE_STATUS, &status); |
| 237 | if (!status) { |
| 238 | glGetShaderInfoLog(shader, sizeof(logBuffer), NULL, logBuffer); |
| 239 | throw RendererException(strf("Failed to compile {} shader: {}\n", name, logBuffer)); |
| 240 | } |
| 241 | |
| 242 | return shader; |
| 243 | }; |
| 244 | |
| 245 | GLuint vertexShader = 0, fragmentShader = 0; |
| 246 | try { |
| 247 | vertexShader = compileShader(GL_VERTEX_SHADER, "vertex"); |
| 248 | fragmentShader = compileShader(GL_FRAGMENT_SHADER, "fragment"); |
| 249 | } |
| 250 | catch (RendererException const& e) { |
| 251 | Logger::error("Shader compile error, using default: {}", e.what()); |
| 252 | if (vertexShader) glDeleteShader(vertexShader); |
| 253 | if (fragmentShader) glDeleteShader(fragmentShader); |
| 254 | vertexShader = compileShader(GL_VERTEX_SHADER, DefaultVertexShader); |
| 255 | fragmentShader = compileShader(GL_FRAGMENT_SHADER, DefaultFragmentShader); |
| 256 | } |
| 257 | |
| 258 | GLuint program = glCreateProgram(); |
| 259 | |
| 260 | if (vertexShader) |
| 261 | glAttachShader(program, vertexShader); |
| 262 | if (fragmentShader) |
| 263 | glAttachShader(program, fragmentShader); |
| 264 | glLinkProgram(program); |
| 265 | |
| 266 | if (vertexShader) |
| 267 | glDeleteShader(vertexShader); |
| 268 | if (fragmentShader) |
| 269 | glDeleteShader(fragmentShader); |
| 270 | |
| 271 | glGetProgramiv(program, GL_LINK_STATUS, &status); |
| 272 | if (!status) { |
| 273 | glGetProgramInfoLog(program, sizeof(logBuffer), NULL, logBuffer); |
| 274 | glDeleteProgram(program); |
no test coverage detected