Skip to content

Commit 95616e4

Browse files
committed
Make shaders more portable
1 parent dcffe3f commit 95616e4

File tree

4 files changed

+29
-56
lines changed

4 files changed

+29
-56
lines changed

src/shadermanager.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ static float wrapClamp(float n, float min, float max)
2222
static const QString VERTEX_SHADER_SRC = ":/qt/qml/ScratchCPP/Render/shaders/sprite.vert";
2323
static const QString FRAGMENT_SHADER_SRC = ":/qt/qml/ScratchCPP/Render/shaders/sprite.frag";
2424

25+
#if defined(Q_OS_WASM)
26+
static const QString SHADER_PREFIX = ""; // compiles, but doesn't work?
27+
#elif defined(Q_OS_ANDROID)
28+
static const QString SHADER_PREFIX = "#version 300 es\n";
29+
#else
30+
static const QString SHADER_PREFIX = "#version 140\n";
31+
#endif
32+
2533
static const char *TEXTURE_UNIT_UNIFORM = "u_skin";
2634

2735
static const std::unordered_map<ShaderManager::Effect, const char *>
@@ -58,7 +66,7 @@ ShaderManager::ShaderManager(QObject *parent) :
5866
QByteArray vertexShaderSource;
5967
QFile vertSource(VERTEX_SHADER_SRC);
6068
vertSource.open(QFile::ReadOnly);
61-
vertexShaderSource = "#version 330 core\n" + vertSource.readAll();
69+
vertexShaderSource = SHADER_PREFIX.toUtf8() + vertSource.readAll();
6270

6371
m_vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, this);
6472
m_vertexShader->compileSourceCode(vertexShaderSource);
@@ -150,7 +158,7 @@ QOpenGLShaderProgram *ShaderManager::createShaderProgram(const std::unordered_ma
150158
return nullptr;
151159

152160
// Version must be defined in the first line
153-
QByteArray fragSource = "#version 330\n";
161+
QByteArray fragSource = SHADER_PREFIX.toUtf8();
154162

155163
// Add defines for the effects
156164
for (const auto &[effect, value] : effectValues) {

src/shaders/sprite.frag

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
// Ported from https://github.com/scratchfoundation/scratch-render/blob/4090e62e8abf427e55c83448da9b0df26120d2fb/src/shaders/sprite.frag
22

3+
#undef lowp
4+
#undef mediump
5+
#undef highp
6+
7+
precision mediump float;
8+
39
#ifdef ENABLE_color
410
uniform float u_color;
511
#endif // ENABLE_color
@@ -12,8 +18,7 @@ uniform float u_brightness;
1218
uniform float u_ghost;
1319
#endif // ENABLE_ghost
1420

15-
in vec2 v_texCoord;
16-
//out vec4 FragColor;
21+
varying vec2 v_texCoord;
1722
uniform sampler2D u_skin;
1823

1924
// Add this to divisors to prevent division by 0, which results in NaNs propagating through calculations.

src/shaders/sprite.vert

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
layout (location = 0) in vec2 a_position;
2-
layout (location = 1) in vec2 a_texCoord;
1+
attribute vec2 a_position;
2+
attribute vec2 a_texCoord;
33

4-
out vec2 v_texCoord;
4+
varying vec2 v_texCoord;
55

66
void main() {
77
gl_Position = vec4(a_position, 0.0, 1.0);

test/shadermanager/shadermanager_test.cpp

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -83,66 +83,26 @@ TEST_F(ShaderManagerTest, Instance)
8383

8484
TEST_F(ShaderManagerTest, GetShaderProgram)
8585
{
86-
static const QByteArray vertHeader = "#version 330 core\n#define lowp\n#define mediump\n#define highp\n#line 1\n";
87-
static const QByteArray fragHeader =
88-
"#version 330\n#ifdef GL_KHR_blend_equation_advanced\n#extension GL_ARB_fragment_coord_conventions : enable\n#extension GL_KHR_blend_equation_advanced : enable\n#endif\n#define lowp\n#define "
89-
"mediump\n#define highp\n#line 1\n";
90-
91-
// Color and ghost
9286
ShaderManager manager;
93-
const std::unordered_map<ShaderManager::Effect, double> effects1 = { { ShaderManager::Effect::Color, 64.9 }, { ShaderManager::Effect::Ghost, 12.5 } };
87+
const std::unordered_map<ShaderManager::Effect, double> effects = { { ShaderManager::Effect::Color, 64.9 }, { ShaderManager::Effect::Ghost, 12.5 } };
9488

95-
QOpenGLShaderProgram *program1 = manager.getShaderProgram(effects1);
96-
ASSERT_EQ(program1->parent(), &manager);
97-
ASSERT_TRUE(program1->isLinked());
89+
QOpenGLShaderProgram *program = manager.getShaderProgram(effects);
90+
ASSERT_EQ(program->parent(), &manager);
91+
ASSERT_TRUE(program->isLinked());
9892

99-
auto shaders = program1->shaders();
93+
auto shaders = program->shaders();
10094
ASSERT_EQ(shaders.size(), 2);
10195
QOpenGLShader *vert = shaders[0];
10296
QOpenGLShader *frag = shaders[1];
10397
ASSERT_EQ(vert->shaderType(), QOpenGLShader::Vertex);
104-
ASSERT_EQ(vert->sourceCode(), vertHeader + m_vertexShader);
105-
ASSERT_EQ(frag->shaderType(), QOpenGLShader::Fragment);
106-
ASSERT_EQ(frag->sourceCode(), fragHeader + "#define ENABLE_ghost\n#define ENABLE_color\n" + m_fragmentShader);
107-
108-
// Brightness and ghost
109-
const std::unordered_map<ShaderManager::Effect, double> effects2 = { { ShaderManager::Effect::Brightness, 64.9 }, { ShaderManager::Effect::Ghost, 12.5 } };
110-
111-
QOpenGLShaderProgram *program2 = manager.getShaderProgram(effects2);
112-
ASSERT_EQ(program2->parent(), &manager);
113-
ASSERT_TRUE(program2->isLinked());
114-
115-
shaders = program2->shaders();
116-
ASSERT_EQ(shaders.size(), 2);
117-
vert = shaders[0];
118-
frag = shaders[1];
119-
ASSERT_EQ(vert->shaderType(), QOpenGLShader::Vertex);
120-
ASSERT_EQ(vert->sourceCode(), vertHeader + m_vertexShader);
12198
ASSERT_EQ(frag->shaderType(), QOpenGLShader::Fragment);
122-
ASSERT_EQ(frag->sourceCode(), fragHeader + "#define ENABLE_ghost\n#define ENABLE_brightness\n" + m_fragmentShader);
12399

124100
// Test shader program cache
125-
QOpenGLShaderProgram *program = manager.getShaderProgram(effects1);
126-
ASSERT_EQ(program, program1);
101+
program = manager.getShaderProgram(effects);
102+
ASSERT_EQ(program, program);
127103

128-
program = manager.getShaderProgram(effects2);
129-
ASSERT_EQ(program, program2);
130-
131-
// Color and brightness where color effect value is zero
132-
const std::unordered_map<ShaderManager::Effect, double> effects3 = { { ShaderManager::Effect::Color, 0.0 }, { ShaderManager::Effect::Brightness, 22.3 } };
133-
134-
program = manager.getShaderProgram(effects3);
135-
ASSERT_EQ(program->parent(), &manager);
136-
ASSERT_TRUE(program->isLinked());
137-
138-
shaders = program->shaders();
139-
ASSERT_EQ(shaders.size(), 2);
140-
vert = shaders[0];
141-
frag = shaders[1];
142-
ASSERT_EQ(vert->shaderType(), QOpenGLShader::Vertex);
143-
ASSERT_EQ(vert->sourceCode(), vertHeader + m_vertexShader);
144-
ASSERT_EQ(frag->shaderType(), QOpenGLShader::Fragment);
145-
ASSERT_EQ(frag->sourceCode(), fragHeader + "#define ENABLE_brightness\n" + m_fragmentShader);
104+
program = manager.getShaderProgram(effects);
105+
ASSERT_EQ(program, program);
146106
}
147107

148108
TEST_F(ShaderManagerTest, SetUniforms)

0 commit comments

Comments
 (0)