File indexing completed on 2024-12-22 04:12:46
0001 /* 0002 * SPDX-FileCopyrightText: 2016 Julian Thijssen <julianthijssen@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "canvas/kis_display_filter.h" 0008 0009 #include <QOpenGLShaderProgram> 0010 #include <QByteArray> 0011 #include <QString> 0012 0013 #include <unordered_map> 0014 #include <string> 0015 #include <stdexcept> 0016 0017 #include <map> 0018 0019 /** 0020 * An enum for storing all uniform names used in shaders 0021 */ 0022 enum Uniform { ModelViewProjection, TextureMatrix, ViewportScale, 0023 TexelSize, Texture0, Texture1, FixedLodLevel, FragmentColor }; 0024 0025 /** 0026 * A wrapper class over Qt's QOpenGLShaderProgram to 0027 * provide access to uniform locations without 0028 * having to store them as constants next to the shader. 0029 */ 0030 class KisShaderProgram : public QOpenGLShaderProgram { 0031 public: 0032 /** 0033 * Stores the mapping of uniform enums to actual shader uniform names. 0034 * The actual shader names are necessary for calls to uniformLocation. 0035 */ 0036 static std::map<Uniform, const char *> names; 0037 0038 /** 0039 * Stores uniform location in cache if it is called for the first time 0040 * and retrieves the location from the map on subsequent calls. 0041 */ 0042 int location(Uniform uniform) { 0043 std::map<Uniform, int>::const_iterator it = locationMap.find(uniform); 0044 if (it != locationMap.end()) { 0045 return it->second; 0046 } else { 0047 int location = uniformLocation(names[uniform]); 0048 locationMap[uniform] = location; 0049 return location; 0050 } 0051 } 0052 private: 0053 std::map<Uniform, int> locationMap; 0054 }; 0055 0056 /** 0057 * A wrapper class over C++ Runtime Error, specifically to record 0058 * failures in shader compilation. Only thrown in KisOpenGLShaderLoader. 0059 */ 0060 class ShaderLoaderException : public std::runtime_error { 0061 public: 0062 ShaderLoaderException(QString error) : std::runtime_error(error.toStdString()) { } 0063 }; 0064 0065 /** 0066 * A utility class for loading various shaders we use in Krita. It provides 0067 * specific methods for shaders that pick the correct vertex and fragment files 0068 * depending on the availability of OpenGL3. Additionally, it provides a generic 0069 * shader loading method to prevent duplication. 0070 */ 0071 class KisOpenGLShaderLoader { 0072 public: 0073 KisShaderProgram *loadDisplayShader(QSharedPointer<KisDisplayFilter> displayFilter, bool useHiQualityFiltering); 0074 KisShaderProgram *loadCheckerShader(); 0075 KisShaderProgram *loadSolidColorShader(); 0076 0077 private: 0078 KisShaderProgram *loadShader(QString vertPath, QString fragPath, QByteArray vertHeader, QByteArray fragHeader); 0079 };