///////////////////////////////////////////////////////
| 845 | |
| 846 | //////////////////////////////////////////////////////////// |
| 847 | bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometryShaderCode, std::string_view fragmentShaderCode) |
| 848 | { |
| 849 | const TransientContextLock lock; |
| 850 | |
| 851 | // First make sure that we can use shaders |
| 852 | if (!isAvailable()) |
| 853 | { |
| 854 | err() << "Failed to create a shader: your system doesn't support shaders " |
| 855 | << "(you should test Shader::isAvailable() before trying to use the Shader class)" << std::endl; |
| 856 | return false; |
| 857 | } |
| 858 | |
| 859 | // Make sure we can use geometry shaders |
| 860 | if (!geometryShaderCode.empty() && !isGeometryAvailable()) |
| 861 | { |
| 862 | err() << "Failed to create a shader: your system doesn't support geometry shaders " |
| 863 | << "(you should test Shader::isGeometryAvailable() before trying to use geometry shaders)" << std::endl; |
| 864 | return false; |
| 865 | } |
| 866 | |
| 867 | // Create the program |
| 868 | const GLEXT_GLhandle shaderProgram = glCheck(GLEXT_glCreateProgramObject()); |
| 869 | |
| 870 | // Helper function for shader creation |
| 871 | const auto createAndAttachShader = |
| 872 | [shaderProgram](GLenum shaderType, const char* shaderTypeStr, std::string_view shaderCode) |
| 873 | { |
| 874 | // Create and compile the shader |
| 875 | const GLEXT_GLhandle shader = glCheck(GLEXT_glCreateShaderObject(shaderType)); |
| 876 | const GLcharARB* sourceCode = shaderCode.data(); |
| 877 | const auto sourceCodeLength = static_cast<GLint>(shaderCode.length()); |
| 878 | glCheck(GLEXT_glShaderSource(shader, 1, &sourceCode, &sourceCodeLength)); |
| 879 | glCheck(GLEXT_glCompileShader(shader)); |
| 880 | |
| 881 | // Check the compile log |
| 882 | GLint success = 0; |
| 883 | glCheck(GLEXT_glGetObjectParameteriv(shader, GLEXT_GL_OBJECT_COMPILE_STATUS, &success)); |
| 884 | if (success == GL_FALSE) |
| 885 | { |
| 886 | std::array<char, 1024> log{}; |
| 887 | glCheck(GLEXT_glGetInfoLog(shader, static_cast<GLsizei>(log.size()), nullptr, log.data())); |
| 888 | err() << "Failed to compile " << shaderTypeStr << " shader:" << '\n' << log.data() << std::endl; |
| 889 | glCheck(GLEXT_glDeleteObject(shader)); |
| 890 | glCheck(GLEXT_glDeleteObject(shaderProgram)); |
| 891 | return false; |
| 892 | } |
| 893 | |
| 894 | // Attach the shader to the program, and delete it (not needed anymore) |
| 895 | glCheck(GLEXT_glAttachObject(shaderProgram, shader)); |
| 896 | glCheck(GLEXT_glDeleteObject(shader)); |
| 897 | return true; |
| 898 | }; |
| 899 | |
| 900 | // Create the vertex shader if needed |
| 901 | if (!vertexShaderCode.empty()) |
| 902 | if (!createAndAttachShader(GLEXT_GL_VERTEX_SHADER, "vertex", vertexShaderCode)) |
| 903 | return false; |
| 904 |
nothing calls this directly
no test coverage detected