12#ifndef GAMP_GLSLSHADERCODE_HPP_
13#define GAMP_GLSLSHADERCODE_HPP_
28 using namespace gamp::render::gl;
113 struct Private{
explicit Private() =
default; };
119 : m_shaderBinaryFormat(0), m_shaderType(0), m_id(0), m_compiled(
false)
121 if(sources.size() != count) {
122 jau_ERR_PRINT(
"shader number (%zu) and sourceFiles array (%zu) of different length.", count, sources.size());
130 m_shader.reserve(count);
131 m_shader.resize(count, 0); } ) ) {
134 m_shaderSource = sources;
147 ShaderCodeSRef res = std::make_shared<ShaderCode>(Private(), type, count, sources);
148 if( res->isValid() ) {
155 ShaderCode(Private, GLenum type,
size_t count, GLenum binFormat,
const bytes_t& binary) noexcept
156 : m_shaderBinaryFormat(0), m_shaderType(0), m_id(0), m_compiled(
false)
163 m_shader.reserve(count);
164 m_shader.resize(count, 0); } ) ) {
168 m_shaderBinaryFormat = binFormat;
169 m_shaderBinary = binary;
181 ShaderCodeSRef res = std::make_shared<ShaderCode>(Private(), type, count, binFormat, binary);
182 if( res->isValid() ) {
212 one_string.reserve(1);
213 one_string.resize(1,
"");
214 const size_t sourceFileCount = sourceFiles.size();
217 if(sourceFileCount > 0) {
219 shaderSources.reserve(sourceFileCount);
220 shaderSources.resize(sourceFileCount, one_string);
221 for(
size_t i=0; i<sourceFileCount && ok; ++i) {
222 ok = readShaderSource(sourceFiles[i], shaderSources[i][0]);
225 return ok ?
create(type, count, shaderSources) :
nullptr;
245 static ShaderCodeRef
create(
GL&
gl, GLenum type,
size_t count,
246 const std::vector<Uri>& sourceLocations,
bool mutableStringBuilder)
noexcept {
251 CharSequence[][] shaderSources = null;
252 if(null!=sourceLocations) {
254 shaderSources =
new CharSequence[sourceLocations.length][1];
255 for(
int i=0; i<sourceLocations.length; i++) {
257 shaderSources[i][0] = readShaderSource(sourceLocations[i], mutableStringBuilder);
258 }
catch (
final IOException ioe) {
259 throw RuntimeException(
"readShaderSource("+sourceLocations[i]+
") error: ", ioe);
261 if(null == shaderSources[i][0]) {
262 shaderSources = null;
266 if(null==shaderSources) {
269 return new ShaderCode(type, count, shaderSources);
287 public static ShaderCode create(
final int type,
final int count,
final Class<?> context,
int binFormat,
final String binaryFile)
noexcept {
289 if(null!=binaryFile && 0<=binFormat) {
292 }
catch (
final IOException ioe) {
293 throw RuntimeException(
"readShaderBinary("+binaryFile+
") error: ", ioe);
336 case GL_VERTEX_SHADER:
338 case GL_FRAGMENT_SHADER:
340 case GL_GEOMETRY_SHADER:
342 case GL_TESS_CONTROL_SHADER:
344 case GL_TESS_EVALUATION_SHADER:
346 case GL_COMPUTE_SHADER:
460 srcPaths.resize(srcBasenames.size());
462 if( !srcRoot.empty() ) {
463 for(
size_t i=0; i<srcPaths.size(); ++i) {
464 srcPaths[i] =
string_t(srcRoot).append(
"/").append(srcBasenames[i]).append(
".").append(srcSuffix);
467 for(
size_t i=0; i<srcPaths.size(); ++i) {
468 srcPaths[i] =
string_t(srcBasenames[i]).append(
".").append(srcSuffix);
471 res =
create(
gl, type, count, srcPaths);
476 if( !srcPathsString.empty() ) {
477 srcPathsString.append(
";");
479 srcPathsString.append(s);
482 if( !binBasename.empty() ) {
485 for(GLenum bFmt : binFmts) {
487 if(bFmtPath.empty())
continue;
488 binFileName =
string_t(binRoot).append(
"/").append(bFmtPath).append(
"/").append(binBasename).append(
".").append(binSuffix);
571 return create(
gl, type, count, srcRoot, srcBasenames,
"", binRoot, binBasename,
"");
630 return create(
gl, type, 1, srcRoot, srcBasenames, srcSuffixOpt, binRoot, basename, binSuffixOpt);
681 return create(
gl, type, srcRoot, binRoot, basename,
"",
"");
685 constexpr size_t id() const noexcept {
return m_id; }
688 constexpr bool isValid() const noexcept {
return 0 != m_id; }
691 constexpr bool isCompiled() const noexcept {
return m_compiled; }
707 if(!m_shaderSource.empty()) {
714 }
else if(!m_shaderBinary.empty()) {
716 m_shaderBinaryFormat, m_shaderBinary,
verbose);
729 if(!m_shaderBinary.empty()) {
730 m_shaderBinary.clear();
732 m_shaderSource.clear();
733 m_shaderBinaryFormat=0;
738 if(
this==&rhs) {
return true; }
739 return m_id == rhs.m_id;
741 constexpr std::size_t
hash_code() const noexcept {
return m_id; }
745 r.append(std::to_string(m_id)).append(
", type=").append(
shaderTypeStr())
746 .append(
", valid=").append(std::to_string(
isValid())).append(
", compiled=").append(std::to_string(m_compiled))
747 .append(
", ").append(std::to_string(m_shader.size())).append(
" shader: ");
748 for(GLuint s : m_shader) {
749 r.append(
" ").append(std::to_string(s));
751 if(!m_shaderSource.empty()) {
752 r.append(
", source]");
753 }
else if(!m_shaderBinary.empty()) {
754 r.append(
", binary]");
761 if(m_shaderSource.empty()) {
765 const size_t sourceCount = m_shaderSource.size();
766 const size_t shaderCount = m_shader.size();
768 jau_PLAIN_PRINT(
true,
"ShaderCode[id=%zu, type=%s, valid=%d, compiled=%d, %zu/%zu shader:",
770 if( 0 == shaderCount ) {
773 for(
size_t i=0; i<shaderCount; ++i) {
775 jau_PLAIN_PRINT(
true,
"Shader #%zu/%zu name %u", i, shaderCount, m_shader[i]);
776 jau_PLAIN_PRINT(
true,
"--------------------------------------------------------------");
783 for(
size_t j=0; j<src.size(); j++) {
784 jau_PLAIN_PRINT(
false,
"%4d: // Segment %zu/%zu:", lineno, j, src.size());
785 std::istringstream reader(src[j]);
787 while (std::getline(reader, line)) {
793 jau_PLAIN_PRINT(
true,
"--------------------------------------------------------------");
808 if(m_shaderSource.empty()) {
810 return string_t::npos;
812 const size_t shaderCount = m_shader.size();
813 if(shaderIdx>=shaderCount) {
814 jau_ERR_PRINT(
"shaderIdx %zu not within shader bounds %zu", shaderIdx, shaderCount);
815 return string_t::npos;
817 const size_t sourceCount = m_shaderSource.size();
818 if(shaderIdx>=sourceCount) {
819 jau_ERR_PRINT(
"shaderIdx %zu not within source bounds %zu", shaderIdx, shaderCount);
820 return string_t::npos;
824 jau_ERR_PRINT(
"no shader source at for shader index %zu", shaderIdx);
825 return string_t::npos;
827 size_t curEndIndex = 0;
828 for(
auto & sb : src) {
829 curEndIndex += sb.length();
830 if(fromIndex < curEndIndex) {
831 size_t insertIdx = sb.find(tag, fromIndex);
832 if(string_t::npos != insertIdx) {
833 insertIdx += tag.length();
834 size_t eol = sb.find(
'\n', insertIdx);
835 if(string_t::npos == eol) {
836 eol = sb.find(
'\r', insertIdx);
838 if(string_t::npos != eol) {
841 sb.insert(insertIdx,
"\n");
844 sb.insert(insertIdx,
data);
845 return insertIdx+
data.length();
849 return string_t::npos;
861 if(m_shaderSource.empty()) {
863 return string_t::npos;
865 const size_t shaderCount = m_shader.size();
866 if(shaderIdx>=shaderCount) {
867 jau_ERR_PRINT(
"shaderIdx %zu not within shader bounds %zu", shaderIdx, shaderCount);
868 return string_t::npos;
870 const size_t sourceCount = m_shaderSource.size();
871 if(shaderIdx>=sourceCount) {
872 jau_ERR_PRINT(
"shaderIdx %zu not within source bounds %zu", shaderIdx, shaderCount);
873 return string_t::npos;
877 jau_ERR_PRINT(
"no shader source at for shader index %zu", shaderIdx);
878 return string_t::npos;
880 size_t curEndIndex = 0;
882 for(; j<src.size()-1 && position > curEndIndex; ++j) {
883 curEndIndex += src[j].length();
886 const size_t lastEndIndex = curEndIndex;
887 curEndIndex += src[j].length();
888 if( position > curEndIndex ) {
889 position = curEndIndex;
891 sb.insert(position - lastEndIndex,
data);
892 return position+
data.length();
907 if( !readShaderSource(path,
data) ) {
908 return string_t::npos;
924 if(m_shaderSource.empty() || oldName == newName) {
927 const size_t oldNameLen = oldName.length();
928 const size_t newNameLen = newName.length();
930 const size_t sourceCount = m_shaderSource.size();
931 for(
size_t shaderIdx = 0; shaderIdx<sourceCount; ++shaderIdx) {
933 for(
auto & sb : src) {
935 while(curPos<sb.length()-oldNameLen+1) {
936 const size_t startIdx = sb.find(oldName, curPos);
937 if(string_t::npos != startIdx) {
938 sb.replace(startIdx, oldNameLen, newName);
939 curPos = startIdx + newNameLen;
942 curPos = sb.length();
952 static bool readShaderSource(
const string_t& conn,
string_t& result,
int& lineno)
noexcept {
955 result.append(
"// '"+conn+
"'\n");
957 result.append(
"// included @ line "+std::to_string(lineno)+
": '"+conn+
"'\n");
960 std::ifstream reader(conn);
962 while ( std::getline(reader, line) ) {
964 if (line.starts_with(
"#include ")) {
970 if( s.starts_with(
"\"") && s.ends_with(
"\"")) {
971 s = s.substr(1, s.length()-2);
981 nextConn = includeFile;
984 if( nextConn.empty() ) {
988 jau_PLAIN_PRINT(
true,
"readShaderSource: including '%s' -> '%s'", includeFile, nextConn);
990 lineno = readShaderSource(nextConn, result, lineno);
992 result.append(line +
"\n");
1012 if (!conn.empty()) {
1014 return readShaderSource(conn, result, lineno);
1030 if( !readShaderSource(path, result) ) {
1052 public static ByteBuffer readShaderBinary(
final Class<?> context,
final String path)
noexcept {
1053 final URLConnection conn = IOUtil.getResource(path, context.getClassLoader(), context);
1057 final BufferedInputStream bis =
new BufferedInputStream( conn.getInputStream() );
1059 return IOUtil.copyStream2ByteBuffer( bis );
1061 IOUtil.close(bis,
false);
1070 public static ByteBuffer readShaderBinary(
final Uri binLocation)
noexcept {
1071 final URLConnection conn = IOUtil.openURL(binLocation.toURL(),
"ShaderCode ");
1075 final BufferedInputStream bis =
new BufferedInputStream( conn.getInputStream() );
1077 return IOUtil.copyStream2ByteBuffer( bis );
1079 IOUtil.close(bis,
false);
1086 constexpr static std::string_view
es2_default_precision_vp =
"\nprecision highp float;\nprecision highp int;\n/*precision lowp sampler2D;*/\n/*precision lowp samplerCube;*/\n";
1088 constexpr static std::string_view
es2_default_precision_fp =
"\nprecision mediump float;\nprecision mediump int;\n/*precision lowp sampler2D;*/\n/*precision lowp samplerCube;*/\n";
1102 constexpr static std::string_view
gl3_default_precision_fp =
"\nprecision highp float;\nprecision mediump int;\n/*precision mediump sampler2D;*/\n";
1105 constexpr static std::string_view
REQUIRE =
"require";
1107 constexpr static std::string_view
ENABLE =
"enable";
1109 constexpr static std::string_view
DISABLE =
"disable";
1111 constexpr static std::string_view
WARN =
"warn";
1114 constexpr static std::string_view vp_130_defines =
1115 "#define attribute in\n"
1116 "#define varying out\n"
1118 constexpr static std::string_view vp_100_defines =
1120 constexpr static std::string_view fp_130_defines =
1121 "#define varying in\n"
1123 "out vec4 mgl_FragColor;\n"
1124 "#define texture2D texture\n";
1126 constexpr static std::string_view fp_100_defines =
1128 "#define mgl_FragColor gl_FragColor\n";
1141 return "#extension " + extensionName +
" : " + behavior +
"\n";
1163 std::string_view defaultPrecision;
1164 if(
gl.glProfile().nativeGLES3() ) {
1165 switch ( m_shaderType ) {
1166 case GL_VERTEX_SHADER:
1168 case GL_FRAGMENT_SHADER:
1170 case GL_COMPUTE_SHADER:
1173 defaultPrecision =
"";
1176 }
else if(
gl.glProfile().nativeGLES2() ) {
1177 switch ( m_shaderType ) {
1178 case GL_VERTEX_SHADER:
1180 case GL_FRAGMENT_SHADER:
1183 defaultPrecision =
"";
1188 switch ( m_shaderType ) {
1189 case GL_VERTEX_SHADER:
1190 case GL_GEOMETRY_SHADER:
1191 case GL_TESS_CONTROL_SHADER:
1192 case GL_TESS_EVALUATION_SHADER:
1194 case GL_FRAGMENT_SHADER:
1196 case GL_COMPUTE_SHADER:
1199 defaultPrecision =
"";
1203 defaultPrecision =
"";
1205 if( defaultPrecision.length() > 0 ) {
1213 if(
gl.glProfile().nativeGLES() ) {
1221 if( !
gl.glProfile().nativeGLES() ) {
1237 if ( GL_VERTEX_SHADER == m_shaderType ) {
1245 }
else if ( GL_FRAGMENT_SHADER == m_shaderType ) {
1274 if( preludeVersion ) {
1279 if( addDefaultPrecision ) {
1282 if( addDefaultDefines ) {
1302 if( preludeVersion ) {
1307 if(
gl.glProfile().nativeGLES() && esDefaultPrecision.length()>0 ) {
1312 if( addDefaultDefines ) {
1325 GLenum m_shaderBinaryFormat;
1327 GLenum m_shaderType;
1331 static size_t nextID() {
return m_nextID++; }
1332 static std::atomic<size_t> m_nextID;
1351 return a.hash_code();
1356 return a->hash_code();
Convenient shader code class to use and instantiate vertex or fragment programs.
size_t insertShaderSource(size_t shaderIdx, size_t position, stringview_t data) noexcept
Adds data at position in shader source for shader shaderIdx.
ShaderCode(Private, GLenum type, size_t count, const source_list_t &sources) noexcept
Private ctor for `ShaderCodeRef create(...).
static constexpr bool requiresGL3DefaultPrecision(const GL &gl) noexcept
Returns true, if GL3 GLSL version requires default precision, i.e.
static constexpr std::string_view gl3_default_precision_fp
Default precision of GLSL ≥ 1.30 as required until < 1.50 for fragment-shader: {@value gl3_default_pr...
static ShaderCodeSRef create(GL &gl, GLenum type, size_t count, stringview_t srcRoot, const string_list_t &srcBasenames, stringview_t binRoot, stringview_t binBasename) noexcept
Simplified variation of create(GL2ES2, int, int, Class, String, String[], String, String,...
static ShaderCodeSRef create(GL &gl, GLenum type, stringview_t srcRoot, stringview_t binRoot, stringview_t basename, stringview_t srcSuffixOpt, stringview_t binSuffixOpt) noexcept
Simplified variation of create(GL2ES2, int, int, Class, String, String[], String, String,...
static constexpr std::string_view SUFFIX_TESS_CONTROL_BINARY
Unique resource suffix for GL4#GL_TESS_CONTROL_SHADER in binary: {@value}
GLenum shaderType() const noexcept
constexpr bool operator==(const ShaderCode &rhs) const noexcept
constexpr std::size_t hash_code() const noexcept
constexpr size_t id() const noexcept
Returns the unique shader id for successfully created instances, zero if instance creation failed.
static ShaderCodeSRef create(GL &gl, GLenum type, stringview_t srcRoot, stringview_t binRoot, stringview_t basename) noexcept
Simplified variation of create(GL2ES2, int, Class, String, String, String, String,...
static string_t createExtensionDirective(const string_t &extensionName, const string_t &behavior)
Creates a GLSL extension directive.
size_t defaultShaderCustomization(const GL &gl, bool preludeVersion, const string_t &esDefaultPrecision, bool addDefaultDefines=true)
Default customization of this shader source code.
size_t replaceInShaderSource(const string_t &oldName, const string_t &newName) noexcept
Replaces oldName with newName in all shader sources.
static constexpr std::string_view SUFFIX_FRAGMENT_SOURCE
Unique resource suffix for GL2ES2#GL_FRAGMENT_SHADER in source code: {@value}
static constexpr std::string_view WARN
Behavior for GLSL extension directive, see createExtensionDirective(String, String),...
static constexpr std::string_view SUFFIX_COMPUTE_BINARY
Unique resource suffix for GL3ES3#GL_COMPUTE_SHADER in binary: {@value}
static constexpr std::string_view SUFFIX_TESS_EVALUATION_BINARY
Unique resource suffix for GL4#GL_TESS_EVALUATION_SHADER in binary: {@value}
static constexpr std::string_view SUFFIX_TESS_EVALUATION_SOURCE
Unique resource suffix for GL4#GL_TESS_EVALUATION_SHADER in source code: {@value}
void destroy(GL &gl) noexcept
static constexpr std::string_view SUFFIX_VERTEX_SOURCE
Unique resource suffix for GL2ES2#GL_VERTEX_SHADER in source code: {@value}
size_t defaultShaderCustomization(const GL &gl, bool preludeVersion=true, bool addDefaultPrecision=true, bool addDefaultDefines=true)
Default customization of this shader source code.
bool compile(GL &gl, bool verbose=false)
GLenum shaderBinaryFormat() const noexcept
static ShaderCodeSRef create(GL &gl, GLenum type, size_t count, const string_list_t &sourceFiles)
Creates a complete ShaderCode object while reading all shader source of sourceFiles,...
static ShaderCodeSRef create(GLenum type, size_t count, GLenum binFormat, const bytes_t &binary)
static constexpr std::string_view SUFFIX_VERTEX_BINARY
Unique resource suffix for GL2ES2#GL_VERTEX_SHADER in binary: {@value}
static ShaderCodeSRef create(GL &gl, GLenum type, size_t count, stringview_t srcRoot, const string_list_t &srcBasenames, stringview_t srcSuffixOpt, stringview_t binRoot, stringview_t binBasename, stringview_t binSuffixOpt) noexcept
Convenient creation method for instantiating a complete ShaderCode object either from source code usi...
static string_t readShaderSource(stringview_t path) noexcept
Reads shader source from file located in path, returning the string.
constexpr bool isCompiled() const noexcept
Returns true if this instance is valid and compiled.
const bytes_t & shaderBinary() const noexcept
static constexpr std::string_view SUB_PATH_NVIDIA
Unique relative path for binary shader resources for NVIDIA: {@value}
static constexpr std::string_view REQUIRE
Behavior for GLSL extension directive, see createExtensionDirective(String, String),...
static constexpr std::string_view ENABLE
Behavior for GLSL extension directive, see createExtensionDirective(String, String),...
static constexpr std::string_view gl3_default_precision_vp_gp
Default precision of GLSL ≥ 1.30 as required until < 1.50 for vertex-shader or geometry-shader: {@val...
ShaderCode(Private, GLenum type, size_t count, GLenum binFormat, const bytes_t &binary) noexcept
Private ctor for `ShaderCodeRef create(...).
static constexpr std::string_view SUFFIX_TESS_CONTROL_SOURCE
Unique resource suffix for GL4#GL_TESS_CONTROL_SHADER in source code: {@value}
constexpr bool isValid() const noexcept
Returns true if this instance is valid, i.e.
const shader_list_t & shader() const noexcept
string_t shaderTypeStr() const noexcept
static constexpr std::string_view DISABLE
Behavior for GLSL extension directive, see createExtensionDirective(String, String),...
static std::string_view getFileSuffix(bool binary, GLenum type) noexcept
Returns a unique suffix for shader resources as follows:
static bool readShaderSource(stringview_t path0, string_t &result) noexcept
Reads shader source from file located in path and appends it to result.
static constexpr std::string_view SUFFIX_GEOMETRY_BINARY
Unique resource suffix for GL3#GL_GEOMETRY_SHADER in binary: {@value}
size_t addGLSLDefines(const GL &gl, size_t pos) noexcept
Add GLSL version and shader-type dependent defines of this shader source code.
static constexpr std::string_view es3_default_precision_fp
Default precision of ES3 for fragment-shader: {@value es3_default_precision_fp}, same as for vertex-s...
string_t toString() const
static constexpr std::string_view es2_default_precision_vp
Default precision of ES2 for vertex-shader: {@value es2_default_precision_vp}.
static ShaderCodeSRef create(GLenum type, size_t count, const source_list_t &sources)
const source_list_t & shaderSource() const noexcept
static constexpr std::string_view SUFFIX_FRAGMENT_BINARY
Unique resource suffix for GL2ES2#GL_FRAGMENT_SHADER in binary: {@value}
size_t addGLSLVersion(const GL &gl) noexcept
Add GLSL version at the head of this shader source code.
size_t insertShaderSourceFile(size_t shaderIdx, size_t position, const string_t &path) noexcept
Adds shader source located in path, either relative to the location or absolute as-is at position in ...
size_t insertShaderSource(size_t shaderIdx, stringview_t tag, size_t fromIndex, stringview_t data) noexcept
Adds data after the line containing tag.
static constexpr std::string_view SUFFIX_COMPUTE_SOURCE
Unique resource suffix for GL3ES3#GL_COMPUTE_SHADER in source code: {@value}
static constexpr std::string_view es3_default_precision_vp
Default precision of ES3 for vertex-shader: {@value es3_default_precision_vp}.
size_t addDefaultShaderPrecision(const GL &gl, size_t pos)
Adds default precision to source code at given position if required, i.e.
static constexpr std::string_view es2_default_precision_fp
Default precision of ES2 for fragment-shader: {@value es2_default_precision_fp}.
static std::string_view getBinarySubPath(GLenum binFormat) noexcept
Returns a unique relative path for binary shader resources as follows:
static constexpr std::string_view SUFFIX_GEOMETRY_SOURCE
Unique resource suffix for GL3#GL_GEOMETRY_SHADER in source code: {@value}
static constexpr bool requiresDefaultPrecision(const GL &gl) noexcept
Returns true, if GLSL version requires default precision, i.e.
static bool createAndCompileShader(GL &gl, shader_list_t &shader, GLenum shaderType, const source_list_t &sources, bool verbose=false)
Creates shader.size() new shaders, stored in the shader list.
static void deleteShader(GL &, const shader_list_t &shaders) noexcept
static bool createAndLoadShader(GL &gl, shader_list_t &shader, GLenum shaderType, GLenum binFormat, const bytes_t &bin, bool verbose=false)
Creates shader.size() new shaders, stored in the shader list.
static name_list_t getShaderBinaryFormats(GL &gl) noexcept
If supported, queries the natively supported shader binary formats using GL2ES2#GL_NUM_SHADER_BINARY_...
static bool isShaderCompilerAvailable(GL &gl) noexcept
Returns true if a hader compiler is available, otherwise false.
Simple version number class containing a version number either being defined explicit or derived from...
#define jau_PLAIN_PRINT(printPrefix, fmt,...)
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
#define jau_ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
std::ostream & operator<<(std::ostream &os, const T v)
bool do_noexcept(UnaryPredicate p) noexcept
No throw wrap for given unary predicate p action. Returns true for success (no exception),...
bool isAbsolute(std::string_view path) noexcept
Returns true if first character is / or - in case of Windows - \\.
std::string dirname(std::string_view path) noexcept
Return stripped last component from given path separated by /, excluding the trailing separator /.
bool exists(const std::string &path, bool verbose_on_error=false) noexcept
Returns true if path exists and is accessible.
@ null
Denotes a func::null_target_t.
std::vector< uint8_t > bytes_t
std::shared_ptr< ShaderCode > ShaderCodeSRef
std::vector< GLenum > name_list_t
std::string_view stringview_t
std::vector< string_t > string_list_t
std::vector< GLuint > shader_list_t
std::vector< string_list_t > source_list_t
static constexpr jau::util::VersionNumber Version1_30
Version 1.30, i.e.
static constexpr GLenum GL_NVIDIA_PLATFORM_BINARY_NV
static constexpr jau::util::VersionNumber Version1_50
Version 1.50, i.e.
constexpr std::string_view shaderTypeString(GLenum type) noexcept
constexpr bool isValidShaderType(GLenum type) noexcept
@ verbose
Verbose operations (debugging).
std::string resolve_asset(const std::string &asset_file, bool lookup_direct=false) noexcept
void trimInPlace(std::string &s) noexcept
trim in place
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
std::size_t operator()(gamp::render::gl::glsl::ShaderCodeSRef const &a) const noexcept
std::size_t operator()(gamp::render::gl::glsl::ShaderCode const &a) const noexcept