void App::compileShader(const char *shader_src, bool recompile) { // clean up error log if (compile_error_log) { delete [] compile_error_log; compile_error_log = nullptr; } bool is_compiled, is_linked; // compile newly loaded shader is_compiled = shader.compileAndAttach(GL_FRAGMENT_SHADER, shader_src); if (!is_compiled) { compile_error_log = shader.getShaderCompileErrorLog(GL_FRAGMENT_SHADER); goto shader_compilation_failed; } is_linked = shader.link(); if (!is_linked) { compile_error_log = shader.getLinkErrorLog(); goto shader_compilation_failed; } if (recompile) { // try to migrate uniform data ShaderUniform *old_uniforms = uniforms; uniforms = nullptr; u8 *old_uniform_data = uniform_data; uniform_data = nullptr; int old_uniform_count = uniform_count; parseUniforms(); if (old_uniform_count) { transferUniformData(old_uniforms, old_uniform_count); assert(old_uniforms); delete [] old_uniforms; assert(old_uniform_data); delete [] old_uniform_data; } } else { parseUniforms(); // load uniform values from disk readUniformData(); } return; // success shader_compilation_failed: assert(compile_error_log); // logically eq. to shader did not compile // use error shader shader.compileAndAttach(GL_FRAGMENT_SHADER, error_frag_src); shader.link(); shader.use(); glUniform1f(shader.getUniformLocation("u_error_time"), u_time); }
void App::readUniformData() { if (!shader_filepath) return; size_t uniform_filepath_len = strlen(shader_filepath)+strlen(uniformdata_ext); char *uniform_filepath = new char[uniform_filepath_len+1]; strcpy(uniform_filepath, shader_filepath); strcat(uniform_filepath, uniformdata_ext); FILE *file = fopen(uniform_filepath, "rb"); delete [] uniform_filepath; if (!file) return; u32 fourcc; fread(&fourcc, sizeof(u32), 1, file); u32 version; fread(&version, sizeof(u32), 1, file); if (fourcc != *((u32*)uniformdata_fourcc) || version != uniformdata_version) { LOGE("Not a valid uniformdata file: %s %d %d", uniform_filepath, *((u32*)uniformdata_fourcc), fourcc); fclose(file); return; } int loaded_uniform_count; ShaderUniform *loaded_uniforms; size_t loaded_uniform_data_size; u8 *loaded_uniform_data; fread(&loaded_uniform_count, sizeof(int), 1, file); fread(&loaded_uniform_data_size, sizeof(size_t), 1, file); assert(loaded_uniform_count > 0 && loaded_uniform_data_size > 0); loaded_uniforms = new ShaderUniform[loaded_uniform_count]; loaded_uniform_data = new u8[loaded_uniform_data_size]; fread(loaded_uniforms, sizeof(ShaderUniform), loaded_uniform_count, file); fread(loaded_uniform_data, sizeof(u8), loaded_uniform_data_size, file); fclose(file); // convert offsets to pointers for (int lui = 0; lui < loaded_uniform_count; lui++) { loaded_uniforms[lui].data = (u8*)((intptr_t)loaded_uniform_data + (intptr_t)loaded_uniforms[lui].data); } transferUniformData(loaded_uniforms, loaded_uniform_count); delete [] loaded_uniforms; delete [] loaded_uniform_data; }
void App::loadShader(const char *frag_file_path, bool initial) { // clean up if (compile_error_log) { delete [] compile_error_log; compile_error_log = nullptr; } // compile newly loaded shader bool is_compiled = shader.readCompileAndAttach(GL_FRAGMENT_SHADER, frag_file_path); if (!is_compiled) { compile_error_log = shader.getShaderCompileErrorLog(GL_FRAGMENT_SHADER); assert(compile_error_log); // should be logically eq. to !is_compiled // use error shader shader.compileAndAttach(GL_FRAGMENT_SHADER, error_frag_src); shader.link(); shader.use(); glUniform1f(shader.getUniformLocation("u_error_time"), u_time); return; // keep old uniforms } shader.link(); if (initial) { parseUniforms(); // load uniform values from disk readUniformData(); } else { ShaderUniform *old_uniforms = uniforms; uniforms = nullptr; u8 *old_uniform_data = uniform_data; uniform_data = nullptr; int old_uniform_count = uniform_count; parseUniforms(); if (old_uniform_count) { transferUniformData(old_uniforms, old_uniform_count); assert(old_uniforms); delete [] old_uniforms; assert(old_uniform_data); delete [] old_uniform_data; } } }
void App::readUniformData() { if (!file_path) return; size_t uniform_file_path_len = strlen(file_path)+strlen(uniformdata_ext); char *uniform_file_path = new char[uniform_file_path_len+1]; strcpy(uniform_file_path, file_path); strcat(uniform_file_path, uniformdata_ext); FILE *file = fopen(uniform_file_path, "rb"); delete [] uniform_file_path; if (!file) return; int loaded_uniform_count; ShaderUniform *loaded_uniforms; size_t loaded_uniform_data_size; u8 *loaded_uniform_data; fread(&loaded_uniform_count, sizeof(int), 1, file); fread(&loaded_uniform_data_size, sizeof(size_t), 1, file); assert(loaded_uniform_count > 0 && loaded_uniform_data_size > 0); loaded_uniforms = new ShaderUniform[loaded_uniform_count]; loaded_uniform_data = new u8[loaded_uniform_data_size]; fread(loaded_uniforms, sizeof(ShaderUniform), loaded_uniform_count, file); fread(loaded_uniform_data, sizeof(u8), loaded_uniform_data_size, file); fclose(file); // convert offsets to pointers for (int lui = 0; lui < loaded_uniform_count; lui++) { loaded_uniforms[lui].data = (u8*)((intptr_t)loaded_uniform_data + (intptr_t)loaded_uniforms[lui].data); } transferUniformData(loaded_uniforms, loaded_uniform_count); delete [] loaded_uniforms; delete [] loaded_uniform_data; }