diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 1631108a5637..f92d5b280186 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -48,7 +48,6 @@ enum { GPU_SHADER_FLAGS_SPECIAL_OPENSUBDIV = (1 << 0), GPU_SHADER_FLAGS_NEW_SHADING = (1 << 1), GPU_SHADER_FLAGS_SPECIAL_INSTANCING = (1 << 2), - GPU_SHADER_FLAGS_SPECIAL_RESET_LINE = (1 << 3), }; GPUShader *GPU_shader_create( diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 056b3ea7c04e..76323f85dc5b 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -297,7 +297,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, bool use_opensubdiv = false; #endif bool use_instancing = (flags & GPU_SHADER_FLAGS_SPECIAL_INSTANCING) != 0; - bool resetline = (flags & GPU_SHADER_FLAGS_SPECIAL_RESET_LINE) != 0; GLint status; GLchar log[5000]; GLsizei length = 0; @@ -336,7 +335,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, gpu_shader_standard_extensions(standard_extensions, geocode != NULL); if (vertexcode) { - const char *source[7]; + const char *source[6]; /* custom limit, may be too small, beware */ int num_source = 0; @@ -346,10 +345,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, source[num_source++] = datatoc_gpu_shader_lib_glsl; if (defines) source[num_source++] = defines; - if (resetline) { - /* Print error message with the correct line number corresponding to the passed code */ - source[num_source++] = "#line 0\n"; - } source[num_source++] = vertexcode; glAttachShader(shader->program, shader->vertex); @@ -368,7 +363,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } if (fragcode) { - const char *source[9]; + const char *source[8]; int num_source = 0; source[num_source++] = gpu_shader_version(); @@ -390,10 +385,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, if (defines) source[num_source++] = defines; if (libcode) source[num_source++] = libcode; - if (resetline) { - /* Print error message with the correct line number corresponding to the passed code */ - source[num_source++] = "#line 0\n"; - } source[num_source++] = fragcode; glAttachShader(shader->program, shader->fragment); @@ -412,7 +403,7 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, } if (geocode) { - const char *source[8]; + const char *source[6]; int num_source = 0; source[num_source++] = gpu_shader_version(); @@ -421,10 +412,6 @@ GPUShader *GPU_shader_create_ex(const char *vertexcode, source[num_source++] = datatoc_gpu_shader_lib_glsl; if (defines) source[num_source++] = defines; - if (resetline) { - /* Print error message with the correct line number corresponding to the passed code */ - source[num_source++] = "#line 0\n"; - } source[num_source++] = geocode; glAttachShader(shader->program, shader->geometry); diff --git a/source/gameengine/Rasterizer/RAS_Shader.cpp b/source/gameengine/Rasterizer/RAS_Shader.cpp index 58c15e178f0d..cb5ecc60a984 100644 --- a/source/gameengine/Rasterizer/RAS_Shader.cpp +++ b/source/gameengine/Rasterizer/RAS_Shader.cpp @@ -276,25 +276,46 @@ void RAS_Shader::DeleteShader() } } +std::string RAS_Shader::GetParsedProgram(ProgramType type) const +{ + std::string prog = m_progs[type]; + if (prog.empty()) { + return prog; + } + + const unsigned int pos = prog.find("#version"); + if (pos != -1) { + CM_Warning("found redundant #version directive in shader program, directive ignored."); + const unsigned int nline = prog.find("\n", pos); + CM_Debug(pos << ", " << nline); + prog.erase(pos, nline - pos); + } + + prog.insert(0, "#line 0\n"); + + return prog; +} + bool RAS_Shader::LinkProgram() { - const char *vert; - const char *frag; - const char *geom; + std::string vert; + std::string frag; + std::string geom; if (m_error) { goto program_error; } if (m_progs[VERTEX_PROGRAM].empty() || m_progs[FRAGMENT_PROGRAM].empty()) { - CM_Error("invalid GLSL sources"); + CM_Error("invalid GLSL sources."); return false; } - vert = m_progs[VERTEX_PROGRAM].c_str(); - frag = m_progs[FRAGMENT_PROGRAM].c_str(); - geom = (m_progs[GEOMETRY_PROGRAM].empty()) ? nullptr : m_progs[GEOMETRY_PROGRAM].c_str(); - m_shader = GPU_shader_create_ex(vert, frag, geom, nullptr, nullptr, 0, 0, 0, GPU_SHADER_FLAGS_SPECIAL_RESET_LINE); + vert = GetParsedProgram(VERTEX_PROGRAM); + frag = GetParsedProgram(FRAGMENT_PROGRAM); + geom = GetParsedProgram(GEOMETRY_PROGRAM); + m_shader = GPU_shader_create(vert.c_str(), frag.c_str(), geom.empty() ? nullptr : geom.c_str(), + nullptr, nullptr, 0, 0, 0); if (!m_shader) { goto program_error; } diff --git a/source/gameengine/Rasterizer/RAS_Shader.h b/source/gameengine/Rasterizer/RAS_Shader.h index 011006e8ef6d..63da1e63005c 100644 --- a/source/gameengine/Rasterizer/RAS_Shader.h +++ b/source/gameengine/Rasterizer/RAS_Shader.h @@ -105,6 +105,12 @@ class RAS_Shader RAS_UniformVec m_uniforms; RAS_UniformVecDef m_preDef; + /** Parse shader program to prevent redundant macro directives. + * \param type The program type to parse. + * \return The parsed program. + */ + std::string GetParsedProgram(ProgramType type) const; + // Compiles and links the shader virtual bool LinkProgram(); void ValidateProgram();