|
1 | 1 | #include "StaticGlShaders.h" |
2 | 2 | #include "projectM-opengl.h" |
| 3 | +#include <cstring> |
| 4 | + |
3 | 5 |
|
4 | 6 | namespace { |
5 | 7 | // Variants of shaders for GLSL1.2 |
@@ -770,16 +772,75 @@ StaticGlShaders::StaticGlShaders(bool use_gles) : use_gles_(use_gles) { |
770 | 772 | } |
771 | 773 |
|
772 | 774 | StaticGlShaders::GlslVersion StaticGlShaders::QueryGlslVersion() { |
| 775 | + /* In the linux desktop environment with --use-gles configured, the parsing of the GL_SHADING_LANGUAGE_VERSION |
| 776 | + string comes back as "OpenGL ES GLSL ES 3" |
| 777 | + And I think this was supposed to be parsing somethign like |
| 778 | + "3.10 etc etc" |
| 779 | + This caused exceptions to be raised in the std::stoi section; |
| 780 | + |
| 781 | + So - The parsing will look for <anything> <number> ['.' <number>] [<anything else>] |
| 782 | + and will default to 3.0 for the version in case of errors |
| 783 | + */ |
| 784 | + |
| 785 | + int major = 3; /* 3.0 is default */ |
| 786 | + int minor = 0; |
| 787 | + |
773 | 788 | std::string glsl_version_string = reinterpret_cast<const char *>( |
774 | 789 | glGetString(GL_SHADING_LANGUAGE_VERSION)); |
775 | | - size_t dot_location = glsl_version_string.find('.'); |
776 | | - size_t end_location = glsl_version_string.find(' '); |
777 | | - auto major_string = glsl_version_string.substr(0, dot_location); |
778 | | - auto minor_string = glsl_version_string.substr(dot_location + 1, |
779 | | - end_location - dot_location); |
780 | | - int major = std::stoi(major_string); |
781 | | - int minor = std::stoi(minor_string); |
782 | 790 |
|
| 791 | + size_t version_len = glsl_version_string.length(); |
| 792 | + /* make a c version of the string and do the conversion to integers manually just for this case */ |
| 793 | + if (version_len) { // find the number |
| 794 | + size_t position = 0; |
| 795 | + char *cstr = new char [version_len+1]; |
| 796 | + |
| 797 | + strcpy(cstr,glsl_version_string.c_str()); |
| 798 | + |
| 799 | + /* scan the anything before the number */ |
| 800 | + while (position<version_len) { |
| 801 | + char ch = cstr[position]; |
| 802 | + if ((ch >= '0') && (ch <= '9')) { |
| 803 | + break; |
| 804 | + } |
| 805 | + position++; |
| 806 | + } |
| 807 | + |
| 808 | + /* scan the first number */ |
| 809 | + { |
| 810 | + int possible_major = 0; |
| 811 | + while (position<version_len) { |
| 812 | + char ch = cstr[position]; |
| 813 | + if ((ch >= '0') && (ch <= '9')) { |
| 814 | + possible_major = (possible_major * 10) + ch - '0'; |
| 815 | + } |
| 816 | + else if (ch == '.') { /* got the minor */ |
| 817 | + int possible_minor = 0; |
| 818 | + position++; |
| 819 | + while (position<version_len) { |
| 820 | + ch = cstr[position]; |
| 821 | + if ((ch >= '0') && (ch <= '9')) { |
| 822 | + possible_minor = (possible_minor * 10) + ch - '0'; |
| 823 | + } |
| 824 | + else break; |
| 825 | + position++; |
| 826 | + } /* while scanning the minor version */ |
| 827 | + if (possible_major) { /* set the minor version only if the major number is valid */ |
| 828 | + minor = possible_minor; |
| 829 | + } |
| 830 | + break; // We scanned it |
| 831 | + } |
| 832 | + else { /* not a number or period */ |
| 833 | + break; |
| 834 | + } |
| 835 | + position++; |
| 836 | + } /* while scanning the major number */ |
| 837 | + if (possible_major) { |
| 838 | + major = possible_major; |
| 839 | + } |
| 840 | + } /* scanning block */ |
| 841 | + delete[] cstr; |
| 842 | + } /* if there is a string to parse */ |
| 843 | + |
783 | 844 | return GlslVersion{major, minor}; |
784 | 845 | } |
785 | 846 |
|
|
0 commit comments