110 static constexpr std::string_view
source_dir =
"impl/graph/glsl";
111 static constexpr std::string_view
bin_dir =
"impl/graph/glsl/bin";
114 : m_rs(pmvMat), m_viewport(),
121 constexpr bool initialized() const noexcept {
return m_initialized; }
129 static constexpr std::string_view es2_precision_fp =
"\nprecision mediump float;\nprecision mediump int;\nprecision mediump sampler2D;\n";
131 std::string_view getFragmentShaderPrecision(
GL&
gl)
const noexcept {
132 if(
gl.glProfile().isGLES() ) {
133 return es2_precision_fp;
142 class ShaderModeSelector1 {
144 std::string_view tech;
145 std::string_view sub;
148 static ShaderModeSelector1 selectPass1(
RenderMode renderMode) {
152 static ShaderModeSelector1 selectPass2(
RenderMode renderMode,
int quality,
int sampleCount) {
153 if(
isVBAA(renderMode) ) {
155 if( sampleCount < 2 ) {
156 return PASS2_VBAA_QUAL0_SAMPLES1;
157 }
else if( sampleCount < 4 ) {
158 return PASS2_VBAA_QUAL0_SAMPLES2;
159 }
else if( sampleCount < 8 ) {
160 return PASS2_VBAA_QUAL0_SAMPLES4;
162 return PASS2_VBAA_QUAL0_SAMPLES8;
165 switch( sampleCount ) {
167 case 1:
return PASS2_VBAA_QUAL1_SAMPLES1;
168 case 2:
return PASS2_VBAA_QUAL1_SAMPLES2;
169 case 3:
return PASS2_VBAA_QUAL1_SAMPLES3;
170 case 4:
return PASS2_VBAA_QUAL1_SAMPLES4;
171 case 5:
return PASS2_VBAA_QUAL1_SAMPLES5;
172 case 6:
return PASS2_VBAA_QUAL1_SAMPLES6;
173 case 7:
return PASS2_VBAA_QUAL1_SAMPLES7;
174 default:
return PASS2_VBAA_QUAL1_SAMPLES8;
183 constexpr static ShaderModeSelector1 PASS1_SIMPLE {
"curve",
"_simple", 0 };
186 constexpr static ShaderModeSelector1 PASS1_WEIGHT {
"curve",
"_weight", 0 };
188 constexpr static ShaderModeSelector1 PASS2_MSAA {
"msaa",
"", 0 };
190 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES1 {
"vbaa",
"_flipquad3", 1 };
192 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES2 {
"vbaa",
"_flipquad3", 2 };
194 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES4 {
"vbaa",
"_flipquad3", 4 };
196 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL0_SAMPLES8 {
"vbaa",
"_flipquad3", 8 };
199 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES1 {
"vbaa",
"_bforce_odd", 1 };
201 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES2 {
"vbaa",
"_bforce_even", 2 };
203 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES3 {
"vbaa",
"_bforce_odd", 3 };
205 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES4 {
"vbaa",
"_bforce_even", 4 };
207 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES5 {
"vbaa",
"_bforce_odd", 5 };
209 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES6 {
"vbaa",
"_bforce_even", 6 };
211 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES7 {
"vbaa",
"_bforce_odd", 7 };
213 constexpr static ShaderModeSelector1 PASS2_VBAA_QUAL1_SAMPLES8 {
"vbaa",
"_bforce_even", 8 };
218 ShaderModeSelector1 sms;
219 bool hasFrustumClipping;
220 bool hasColorChannel;
221 bool hasColorTexture;
222 std::string_view colorTexSeqID;
226 ShaderKey(
bool isTwoPass,
bool pass1, ShaderModeSelector1 sms,
227 bool hasFrustumClipping,
bool hasColorChannel,
228 bool hasColorTexture, TextureSequence colorTexSeq,
int colorTexSeqHash)
230 this.isTwoPass = isTwoPass;
233 this.hasFrustumClipping = hasFrustumClipping;
234 this.hasColorChannel = hasColorChannel;
235 this.hasColorTexture = hasColorTexture;
236 if( hasColorTexture ) {
239 this.colorTexSeqID =
"";
241 hashValue = getShaderKey1(isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms, colorTexSeqHash);
244 public final int hashCode() {
return hashValue; }
246 public bool equals(
final Object other) {
247 if(
this == other ) {
return true; }
248 if( !(other instanceof ShaderKey) ) {
251 final ShaderKey o = (ShaderKey)other;
252 return isTwoPass == o.isTwoPass &&
256 sms.ordinal() == o.sms.ordinal() &&
257 hasFrustumClipping == o.hasFrustumClipping &&
258 hasColorChannel == o.hasColorChannel &&
259 hasColorTexture == o.hasColorTexture &&
260 colorTexSeqID.equals(o.colorTexSeqID);
263 public String toString() {
264 return shaderHashToString(hashValue, isTwoPass, pass1, hasFrustumClipping, hasColorChannel, hasColorTexture, sms);
267 private static final boolean UseShaderPrograms0 =
true;
268 private final LongObjectHashMap shaderPrograms0;
269 private final HashMap<ShaderKey, ShaderProgram> shaderPrograms1;
271 private static String shaderHashToString(
final int hashCode,
final boolean isTwoPass,
final boolean pass1,
273 final ShaderModeSelector1 sms) {
274 return "ShaderHash[hash 0x"+Integer.toHexString(hashCode)+
", is2Pass "+
isTwoPass+
", pass1 "+pass1+
277 private static String shaderKeyToString(
final long key,
final boolean isTwoPass,
final boolean pass1,
279 final ShaderModeSelector1 sms) {
280 return "ShaderKey[key 0x"+Long.toHexString(key)+
", is2Pass "+
isTwoPass+
", pass1 "+pass1+
284 private static long getShaderKey0(
final boolean isTwoPass,
final boolean pass1,
286 final ShaderModeSelector1 sms,
final long colorTexSeqHash) {
296 hash |= ( pass1 ? 1L : 0
L ) << 1;
297 hash |= (long)( sms.ordinal() & 0b11111 ) << 2;
298 hash |= ( hasFrustumClipping ? 1L : 0
L ) << 7;
301 hash |= ( colorTexSeqHash & 0xFFFFFFL ) << 32;
304 private static int getShaderKey1(
final boolean isTwoPass,
final boolean pass1,
306 final ShaderModeSelector1 sms,
final int colorTexSeqHash) {
309 hash = ((hash << 5) - hash) + ( pass1 ? 1 : 0 ) ;
312 hash = ((hash << 5) - hash) + sms.ordinal();
313 hash = ((hash << 5) - hash) + ( hasFrustumClipping ? 1 : 0 );
316 hash = ((hash << 5) - hash) + colorTexSeqHash;
320 static ShaderProgramRef createShaderProgram(
GL& gl,
const RenderState& rs,
RenderMode renderMode,
bool pass1,
const jau::fraction_timespec& when) {
323 std::string vertexShaderName, fragmentShaderName;
326 vertexShaderName.append(
"-pass").append(pass1 ?
"1":
"2");
328 vertexShaderName.append(
"-single");
334 if( !rsVp || !rsFp ) {
339 size_t posVp = rsVp->defaultShaderCustomization(gl,
true,
true);
340 size_t posFp = rsFp->defaultShaderCustomization(gl,
true,
true);
341 if( posVp == std::string::npos || posFp == std::string::npos ) {
356 if( rs.usesFrustumClipping() ) {
383 if( posVp == std::string::npos ) {
390 posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/constants.glsl"));
391 if( posFp == std::string::npos ) {
395 posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/uniforms.glsl"));
396 if( posFp == std::string::npos ) {
400 posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/varyings.glsl"));
401 if( posFp == std::string::npos ) {
406 posFp = rsFp->insertShaderSourceFile(0, posFp,
string_t(
source_dir).append(
"/functions.glsl"));
407 if( posFp == std::string::npos ) {
419 std::string passS = pass1 ?
"-pass1-" :
"-pass2-";
422 jau::PLAIN_PRINT(
true,
"RegionRenderer.createShaderProgram.1: segment %s", shaderSegment.c_str());
424 posFp = rsFp->insertShaderSourceFile(0, posFp, shaderSegment);
425 if( posFp == std::string::npos ) {
429 posFp = rsFp->insertShaderSource(0, posFp,
"}\n");
430 if( posFp == std::string::npos ) {
439 if( !sp0->add(gl, rsVp,
true) || !sp0->add(gl, rsFp,
true) ) {
444 sp0->useProgram(gl,
true);
446 m_initialized = sp0->inUse();
447 if( !m_initialized ) {