Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_opengl_shader_loader.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2016 Julian Thijssen <julianthijssen@gmail.com>
3 * SPDX-FileCopyrightText: 2023 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include "opengl/kis_opengl.h"
11#include "kis_config.h"
12
13#include <config-ocio.h>
14
15#include <QFile>
16#include <QMessageBox>
17#include <KLocalizedString>
18
19#define PROGRAM_VERTEX_ATTRIBUTE 0
20#define PROGRAM_TEXCOORD_ATTRIBUTE 1
21
22// Mapping of uniforms to uniform names
23std::map<Uniform, const char *> KisShaderProgram::names = {
24 {ModelViewProjection, "modelViewProjection"},
25 {TextureMatrix, "textureMatrix"},
26 {ViewportScale, "viewportScale"},
27 {TexelSize, "texelSize"},
28 {Texture0, "texture0"},
29 {Texture1, "texture1"},
30 {FixedLodLevel, "fixedLodLevel"},
31 {FragmentColor, "fragColor"}
32};
33
44KisShaderProgram *KisOpenGLShaderLoader::loadShader(QString vertPath, QString fragPath,
45 QByteArray vertHeader, QByteArray fragHeader)
46{
47 bool result;
48
49 KisShaderProgram *shader = new KisShaderProgram();
50
51 // Load vertex shader
52 QByteArray vertSource;
53
55 vertSource.append("#version 300 es\n");
56 } else {
57#ifdef Q_OS_MACOS
58 vertSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
59 vertSource.append("#define texture2D texture\n");
60 vertSource.append("#define texture3D texture\n");
61#else
62 vertSource.append(KisOpenGL::supportsLoD() ? "#version 130\n" : "#version 120\n");
63#endif
64 }
65 vertSource.append(vertHeader);
66 QFile vertexShaderFile(":/" + vertPath);
67 if (!vertexShaderFile.open(QIODevice::ReadOnly)) {
68 throw ShaderLoaderException(QString("%1: %2 - Cause: %3").arg("Failed to open vertex shader source file", vertPath, vertexShaderFile.errorString()));
69 }
70 vertSource.append(vertexShaderFile.readAll());
71
72 result = shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertSource);
73 if (!result)
74 throw ShaderLoaderException(QString("%1: %2 - Cause: %3").arg("Failed to add vertex shader source from file", vertPath, shader->log()));
75
76 // Load fragment shader
77 QByteArray fragSource;
78
80 fragSource.append("#version 300 es\n");
82 fragSource.append("#extension GL_EXT_shader_texture_lod : enable\n");
83 }
84 fragSource.append(
85 "precision mediump float;\n"
86 "precision mediump sampler3D;\n");
87
88 // OpenColorIO doesn't support OpenGL ES.
89 fragSource.append("#define texture2D texture\n");
90 fragSource.append("#define texture3D texture\n");
92 fragSource.append(
93 "#if __VERSION__ < 300\n"
94 "#define textureLod texture2DLodEXT\n"
95 "#endif\n"
96 );
97 }
98 } else {
99#ifdef Q_OS_MACOS
100 fragSource.append(KisOpenGL::hasOpenGL3() ? "#version 150 core\n" : "#version 120\n");
101 fragSource.append("#define texture2D texture\n");
102 fragSource.append("#define texture3D texture\n");
103#else
104 fragSource.append(KisOpenGL::supportsLoD() ? "#version 130\n" : "#version 120\n");
105#endif
106 }
107 fragSource.append(fragHeader);
108 QFile fragmentShaderFile(":/" + fragPath);
109 if (!fragmentShaderFile.open(QIODevice::ReadOnly)) {
110 throw ShaderLoaderException(QString("%1: %2 - Cause: %3").arg("Failed to open fragment shader source file", fragPath, fragmentShaderFile.errorString()));
111 }
112 fragSource.append(fragmentShaderFile.readAll());
113
114 result = shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragSource);
115 if (!result)
116 throw ShaderLoaderException(QString("%1: %2 - Cause: %3").arg("Failed to add fragment shader source from file", fragPath, shader->log()));
117
118 // Bind attributes
119 shader->bindAttributeLocation("a_vertexPosition", PROGRAM_VERTEX_ATTRIBUTE);
120 shader->bindAttributeLocation("a_textureCoordinate", PROGRAM_TEXCOORD_ATTRIBUTE);
121
122 // Link
123 result = shader->link();
124 if (!result)
125 throw ShaderLoaderException(QString("Failed to link shader: ").append(vertPath));
126
127 Q_ASSERT(shader->isLinked());
128
129 return shader;
130}
131
139{
140 QByteArray fragHeader;
141
143 fragHeader.append("#define DIRECT_LOD_FETCH\n");
144 if (useHiQualityFiltering) {
145 fragHeader.append("#define HIGHQ_SCALING\n");
146 }
147 }
148
149 // If we have an OCIO display filter and it contains a function we add
150 // it to our shader header which will sit on top of the fragment code.
151 bool haveDisplayFilter = displayFilter && !displayFilter->program().isEmpty();
152 if (haveDisplayFilter) {
153 fragHeader.append("#define USE_OCIO\n");
154 fragHeader.append(displayFilter->program().toLatin1());
155 }
156
157 QString vertPath, fragPath;
158 // Select appropriate shader files
160 vertPath = "matrix_transform.vert";
161 fragPath = "highq_downscale.frag";
162 } else {
163 vertPath = "matrix_transform_legacy.vert";
164 fragPath = "simple_texture_legacy.frag";
165 }
166
167 KisShaderProgram *shader = loadShader(vertPath, fragPath, QByteArray(), fragHeader);
168
169 return shader;
170}
171
177{
178 QString vertPath, fragPath;
179 // Select appropriate shader files
181 vertPath = "matrix_transform.vert";
182 fragPath = "simple_texture.frag";
183 } else {
184 vertPath = "matrix_transform_legacy.vert";
185 fragPath = "simple_texture_legacy.frag";
186 }
187
188 KisShaderProgram *shader = loadShader(vertPath, fragPath, QByteArray(), QByteArray());
189
190 return shader;
191}
192
198{
199 QString vertPath, fragPath;
200 // Select appropriate shader files
202 vertPath = "solid_color.vert";
203 fragPath = "solid_color.frag";
204 } else {
205 vertPath = "solid_color_legacy.vert";
206 fragPath = "solid_color_legacy.frag";
207 }
208
209 KisShaderProgram *shader = loadShader(vertPath, fragPath, QByteArray(), QByteArray());
210
211 return shader;
212}
KisShaderProgram * loadShader(QString vertPath, QString fragPath, QByteArray vertHeader, QByteArray fragHeader)
KisShaderProgram * loadSolidColorShader()
KisShaderProgram * loadCheckerShader()
KisShaderProgram * loadDisplayShader(QSharedPointer< KisDisplayFilter > displayFilter, bool useHiQualityFiltering)
static bool hasOpenGLES()
static bool supportsLoD()
static bool hasOpenGL3()
static std::map< Uniform, const char * > names
#define PROGRAM_TEXCOORD_ATTRIBUTE
#define PROGRAM_VERTEX_ATTRIBUTE
@ ModelViewProjection