Skip to content

Commit d1314d0

Browse files
hibenglerMischa Spiegelmock
authored andcommitted
There was a bug that existed in open GL ES 2.0 implementations and random textures (#239)
* There was a bug that existed in open GL ES 2.0 implementations where glTexImage2D could not convert GL_RGB formed textures into GL_RGBA while generating the noise textures. The GL error was GL_INVALID_OPERATION(0x502) This probably made the noise textures blank. So a new class was added that has the alpha channel for the values. * Added a fudge for render farming milkdrop where we control the time and the ticks. * User defined time: Got rid of testing code * Attempt to fix WIN32 compile - it doesnt use or need the ability to control the time * Got rid of debug - got rid of minor warning * projectM.hpp - type in ifdef projectM_SDL_main.cpp - there is code added to make the initial random number dependent on the time of day, making the sequence of visualizers more unexpected. But the posix command time does not exist in Win32 land, so we disable it.
1 parent 0996a06 commit d1314d0

File tree

10 files changed

+329
-15
lines changed

10 files changed

+329
-15
lines changed

src/libprojectM/Renderer/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ libRenderer_la_SOURCES = \
1515
Waveform.cpp \
1616
Filters.cpp \
1717
PerlinNoise.cpp \
18+
PerlinNoiseWithAlpha.cpp \
1819
PipelineContext.cpp \
1920
Renderable.cpp \
2021
BeatDetect.cpp \
@@ -28,7 +29,7 @@ libRenderer_la_SOURCES = \
2829
Filters.hpp RenderItemMatcher.hpp Transformation.hpp\
2930
MilkdropWaveform.hpp RenderItemMergeFunction.hpp Texture.hpp\
3031
PerPixelMesh.hpp Renderable.hpp VideoEcho.hpp\
31-
PerlinNoise.hpp Renderer.hpp Waveform.hpp\
32+
PerlinNoise.hpp PerlinNoiseWithAlpha.hpp Renderer.hpp Waveform.hpp\
3233
Pipeline.hpp Shader.hpp\
3334
SOIL2/SOIL2.h SOIL2/stbi_DDS.h\
3435
SOIL2/etc1_utils.h SOIL2/stbi_DDS_c.h\
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* PerlinNoiseWithAlpha.cpp
3+
*
4+
* Created and based on PerlinNoise.hpp
5+
* Created on: Sep 14, 2019
6+
* Author: hibengler
7+
*/
8+
9+
#include "PerlinNoiseWithAlpha.hpp"
10+
#include <iostream>
11+
#include <stdlib.h>
12+
13+
/* The reason for this cousin class is that in Open GLES 2.0 environments,
14+
the glTexImage2d cannot convert from GL_RGB into GL_RGBA
15+
so the TextureManager has to use something that is pre-RGBA
16+
*/
17+
PerlinNoiseWithAlpha::PerlinNoiseWithAlpha()
18+
{
19+
for (int x = 0; x < 256;x++) {
20+
for (int y = 0; y < 256;y++) {
21+
noise_lq[x][y][0] = noise(x , y);
22+
noise_lq[x][y][1] = noise_lq[x][y][0];
23+
noise_lq[x][y][2] = noise_lq[x][y][0];
24+
noise_lq[x][y][3] = 1.f;
25+
}
26+
}
27+
28+
for (int x = 0; x < 32;x++) {
29+
for (int y = 0; y < 32;y++) {
30+
noise_lq_lite[x][y][0] = noise(4*x,16*y);
31+
noise_lq_lite[x][y][1] = noise_lq_lite[x][y][0];
32+
noise_lq_lite[x][y][2] = noise_lq_lite[x][y][0];
33+
noise_lq_lite[x][y][3] = 1.f;
34+
}
35+
}
36+
37+
for (int x = 0; x < 256;x++) {
38+
for (int y = 0; y < 256;y++) {
39+
noise_mq[x][y][0] = InterpolatedNoise((float)x/(float)2.0,(float)y/(float)2.0);
40+
noise_mq[x][y][1] = noise_mq[x][y][0];
41+
noise_mq[x][y][2] = noise_mq[x][y][0];
42+
noise_mq[x][y][3] = 1.f;
43+
}
44+
}
45+
46+
for (int x = 0; x < 256;x++) {
47+
for (int y = 0; y < 256;y++) {
48+
noise_hq[x][y][0] = InterpolatedNoise((float)x/(float)3.0,(float)y/(float)3.0);
49+
noise_hq[x][y][1] = noise_hq[x][y][0];
50+
noise_hq[x][y][2] = noise_hq[x][y][0];
51+
noise_hq[x][y][3] = 1.f;
52+
}
53+
}
54+
55+
for (int x = 0; x < 32;x++) {
56+
for (int y = 0; y < 32;y++) {
57+
for (int z = 0; z < 32;z++) {
58+
noise_lq_vol[x][y][z][0] = noise(x,y,z);
59+
noise_lq_vol[x][y][z][1] = noise_lq_vol[x][y][z][0];
60+
noise_lq_vol[x][y][z][2] = noise_lq_vol[x][y][z][0];
61+
noise_lq_vol[x][y][z][3] = 1.f;
62+
}
63+
}
64+
}
65+
66+
for (int x = 0; x < 32;x++) {
67+
for (int y = 0; y < 32;y++) {
68+
for (int z = 0; z < 32;z++) {
69+
noise_hq_vol[x][y][z][0] = noise(x,y,z);
70+
noise_hq_vol[x][y][z][1] = noise_hq_vol[x][y][z][0];
71+
noise_hq_vol[x][y][z][2] = noise_hq_vol[x][y][z][0];
72+
noise_hq_vol[x][y][z][3] = 1.f;
73+
}
74+
}
75+
}
76+
}
77+
78+
PerlinNoiseWithAlpha::~PerlinNoiseWithAlpha()
79+
{
80+
// TODO Auto-generated destructor stub
81+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* PerlinNoise.hpp
3+
*
4+
* Created and based on PerlinNoise.hpp
5+
* Created on: Sep 14, 2019
6+
* Author: hibengler
7+
*/
8+
9+
10+
/* The reason for this cousin class is that in Open GLES 2.0 environments,
11+
the glTexImage2d cannot convert from GL_RGB into GL_RGBA
12+
so the TextureManager has to use something that is pre-RGBA
13+
*/
14+
#ifndef PERLINNOISEWITHALPHA_HPP_
15+
#define PERLINNOISEWITHALPHA_HPP_
16+
17+
#include <math.h>
18+
19+
class PerlinNoiseWithAlpha
20+
{
21+
public:
22+
23+
float noise_lq[256][256][4];
24+
float noise_lq_lite[32][32][4];
25+
float noise_mq[256][256][4];
26+
float noise_hq[256][256][4];
27+
float noise_lq_vol[32][32][32][4];
28+
float noise_hq_vol[32][32][32][4];
29+
30+
31+
PerlinNoiseWithAlpha();
32+
virtual ~PerlinNoiseWithAlpha();
33+
34+
private:
35+
36+
static inline float noise( int x)
37+
{
38+
x = (x<<13)^x;
39+
return (((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0);
40+
}
41+
42+
static inline float noise(int x, int y)
43+
{
44+
int n = x + y * 57;
45+
return noise(n);
46+
}
47+
48+
static inline float noise(int x, int y, int z)
49+
{
50+
int n = x + y * 57 + z * 141;
51+
return noise(n);
52+
}
53+
54+
static inline float cubic_interp(float v0, float v1, float v2, float v3, float x)
55+
{
56+
float P = (v3 - v2) - (v0 - v1);
57+
float Q = (v0 - v1) - P;
58+
float R = v2 - v0;
59+
60+
return P*pow(x,3) + Q * pow(x,2) + R*x + v1;
61+
}
62+
63+
static inline float InterpolatedNoise(float x, float y)
64+
{
65+
int integer_X = int(x);
66+
float fractional_X = x - integer_X;
67+
68+
int integer_Y = int(y);
69+
float fractional_Y = y - integer_Y;
70+
71+
float a0 = noise(integer_X - 1, integer_Y - 1);
72+
float a1 = noise(integer_X, integer_Y - 1);
73+
float a2 = noise(integer_X + 1, integer_Y - 1);
74+
float a3 = noise(integer_X + 2, integer_Y - 1);
75+
76+
float x0 = noise(integer_X - 1, integer_Y);
77+
float x1 = noise(integer_X, integer_Y);
78+
float x2 = noise(integer_X + 1, integer_Y);
79+
float x3 = noise(integer_X + 2, integer_Y);
80+
81+
float y0 = noise(integer_X + 0, integer_Y + 1);
82+
float y1 = noise(integer_X, integer_Y + 1);
83+
float y2 = noise(integer_X + 1, integer_Y + 1);
84+
float y3 = noise(integer_X + 2, integer_Y + 1);
85+
86+
float b0 = noise(integer_X - 1, integer_Y + 2);
87+
float b1 = noise(integer_X, integer_Y + 2);
88+
float b2 = noise(integer_X + 1, integer_Y + 2);
89+
float b3 = noise(integer_X + 2, integer_Y + 2);
90+
91+
float i0 = cubic_interp(a0 , a1, a2, a3, fractional_X);
92+
float i1 = cubic_interp(x0 , x1, x2, x3, fractional_X);
93+
float i2 = cubic_interp(y0 , y1, y2, y3, fractional_X);
94+
float i3 = cubic_interp(b0 , b1, b2, b3, fractional_X);
95+
96+
return cubic_interp(i0, i1 , i2 , i3, fractional_Y);
97+
98+
}
99+
100+
static inline float perlin_octave_3d(float x,float y, float z,int width, int seed, float period)
101+
{
102+
float freq=1/(float)(period);
103+
104+
int num=(int)(width*freq);
105+
int step_x=(int)(x*freq);
106+
int step_y=(int)(y*freq);
107+
int step_z=(int)(z*freq);
108+
float zone_x=x*freq-step_x;
109+
float zone_y=y*freq-step_y;
110+
float zone_z=z*freq-step_z;
111+
112+
int boxB=step_x+step_y+step_z*num;
113+
int boxC=step_x+step_y+step_z*(num+1);
114+
int boxD=step_x+step_y+step_z*(num+2);
115+
int boxA=step_x+step_y+step_z*(num-1);
116+
117+
float u,a,b,v,noisedata,box;
118+
119+
box = boxA;
120+
noisedata=(box+seed);
121+
u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
122+
a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
123+
b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
124+
v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
125+
float A=cubic_interp(u,a,b,v,zone_y);
126+
127+
box = boxB;
128+
noisedata=(box+seed);
129+
u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
130+
a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
131+
b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
132+
v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
133+
float B=cubic_interp(u,a,b,v,zone_y);
134+
135+
box = boxC;
136+
noisedata=(box+seed);
137+
u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
138+
a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
139+
b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
140+
v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
141+
float C=cubic_interp(u,a,b,v,zone_y);
142+
143+
box = boxD;
144+
noisedata=(box+seed);
145+
u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x);
146+
a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x);
147+
b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x);
148+
v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x);
149+
float D=cubic_interp(u,a,b,v,zone_y);
150+
151+
float value =cubic_interp(A,B,C,D,zone_z);
152+
153+
return value;
154+
}
155+
156+
157+
static inline float perlin_noise_3d(int x, int y, int z, int width, int octaves, int seed, float persistance, float basePeriod)
158+
{
159+
float p = persistance;
160+
float val = 0.0;
161+
162+
for (int i = 0; i<octaves;i++)
163+
{
164+
val += perlin_octave_3d(x,y,z,width,seed,basePeriod) * p;
165+
166+
basePeriod *= 0.5;
167+
p *= persistance;
168+
}
169+
return val;
170+
}
171+
172+
173+
174+
};
175+
176+
#endif /* PERLINNOISEWITHALPHA_HPP_ */

src/libprojectM/Renderer/Renderer.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
Pipeline* Renderer::currentPipe;
1818

19-
2019
class Preset;
2120

2221
Renderer::Renderer(int width, int height, int gx, int gy, BeatDetect *_beatDetect, std::string _presetURL,
@@ -33,7 +32,6 @@ Renderer::Renderer(int width, int height, int gx, int gy, BeatDetect *_beatDetec
3332
this->showstats = false;
3433
this->studio = false;
3534
this->realfps = 0;
36-
3735
/* Set up the v xoffset and vy offset to 0 which is normal Only used for VR */
3836
this->vstartx = 0;
3937
this->vstarty = 0;
@@ -169,7 +167,6 @@ Renderer::Renderer(int width, int height, int gx, int gy, BeatDetect *_beatDetec
169167
glBindBuffer(GL_ARRAY_BUFFER, 0);
170168

171169

172-
173170
// CompositeShaderOutput VAO/VBO's
174171
glGenBuffers(1, &m_vbo_CompositeShaderOutput);
175172
glGenVertexArrays(1, &m_vao_CompositeShaderOutput);

src/libprojectM/Renderer/TextureManager.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,22 @@
2424
#include "Common.hpp"
2525
#include "IdleTextures.hpp"
2626
#include "Texture.hpp"
27-
#include "PerlinNoise.hpp"
27+
/* OpenGL ES 2.0 cant handle converting textures fro GL_RGB to GL_RGBA via glTexImage2D
28+
http://docs.gl/es2/glTexImage2D
29+
30+
This causes a GLError INVALID_OPERATION(0x502) whenever making a new Renderer or resizing it.
2831
32+
So because of this, we switch to a PerlinNoiseWithAlpha class to generate the noise textures.
33+
*/
34+
#ifdef GL_ES_VERSION_2_0
35+
#include "PerlinNoiseWithAlpha.hpp"
36+
#define NOISE_INTERNAL_DATA_FORMAT GL_RGBA
37+
#else
38+
#include "PerlinNoise.hpp"
39+
#define NOISE_INTERNAL_DATA_FORMAT GL_RGB
40+
#endif
2941

42+
3043
#define NUM_BLUR_TEX 6
3144

3245

@@ -94,55 +107,61 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX
94107
blurTextures.push_back(textureBlur);
95108
}
96109

110+
#ifdef GL_ES_VERSION_2_0
111+
std::unique_ptr<PerlinNoiseWithAlpha> noise(new PerlinNoiseWithAlpha());
112+
#else
97113
std::unique_ptr<PerlinNoise> noise(new PerlinNoise());
114+
#endif
98115

99116
GLuint noise_texture_lq_lite;
100117
glGenTextures(1, &noise_texture_lq_lite);
101118
glBindTexture(GL_TEXTURE_2D, noise_texture_lq_lite);
102-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGB, GL_FLOAT, noise->noise_lq_lite);
119+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_lq_lite);
103120
Texture * textureNoise_lq_lite = new Texture("noise_lq_lite", noise_texture_lq_lite, GL_TEXTURE_2D, 32, 32, false);
104121
textureNoise_lq_lite->getSampler(GL_REPEAT, GL_LINEAR);
105122
textures["noise_lq_lite"] = textureNoise_lq_lite;
106123

107124
GLuint noise_texture_lq;
108125
glGenTextures(1, &noise_texture_lq);
109126
glBindTexture(GL_TEXTURE_2D, noise_texture_lq);
110-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_lq);
127+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_lq);
111128
Texture * textureNoise_lq = new Texture("noise_lq", noise_texture_lq, GL_TEXTURE_2D, 256, 256, false);
112129
textureNoise_lq->getSampler(GL_REPEAT, GL_LINEAR);
113130
textures["noise_lq"] = textureNoise_lq;
114131

115132
GLuint noise_texture_mq;
116133
glGenTextures(1, &noise_texture_mq);
117134
glBindTexture(GL_TEXTURE_2D, noise_texture_mq);
118-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_mq);
135+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_mq);
119136
Texture * textureNoise_mq = new Texture("noise_mq", noise_texture_mq, GL_TEXTURE_2D, 256, 256, false);
120137
textureNoise_mq->getSampler(GL_REPEAT, GL_LINEAR);
121138
textures["noise_mq"] = textureNoise_mq;
122139

123140
GLuint noise_texture_hq;
124141
glGenTextures(1, &noise_texture_hq);
125142
glBindTexture(GL_TEXTURE_2D, noise_texture_hq);
126-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_hq);
143+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_hq);
127144
Texture * textureNoise_hq = new Texture("noise_hq", noise_texture_hq, GL_TEXTURE_2D, 256, 256, false);
128145
textureNoise_hq->getSampler(GL_REPEAT, GL_LINEAR);
129146
textures["noise_hq"] = textureNoise_hq;
130147

131148
GLuint noise_texture_lq_vol;
132149
glGenTextures( 1, &noise_texture_lq_vol );
133150
glBindTexture( GL_TEXTURE_3D, noise_texture_lq_vol );
134-
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,GL_RGB ,GL_FLOAT ,noise->noise_lq_vol);
151+
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT ,noise->noise_lq_vol);
135152
Texture * textureNoise_lq_vol = new Texture("noisevol_lq", noise_texture_lq_vol, GL_TEXTURE_3D, 32, 32, false);
136153
textureNoise_lq_vol->getSampler(GL_REPEAT, GL_LINEAR);
137154
textures["noisevol_lq"] = textureNoise_lq_vol;
138155

139156
GLuint noise_texture_hq_vol;
140157
glGenTextures( 1, &noise_texture_hq_vol );
141158
glBindTexture( GL_TEXTURE_3D, noise_texture_hq_vol );
142-
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, GL_RGB, GL_FLOAT, noise->noise_hq_vol);
159+
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_hq_vol);
160+
143161
Texture * textureNoise_hq_vol = new Texture("noisevol_hq", noise_texture_hq_vol, GL_TEXTURE_3D, 32, 32, false);
144162
textureNoise_hq_vol->getSampler(GL_REPEAT, GL_LINEAR);
145163
textures["noisevol_hq"] = textureNoise_hq_vol;
164+
146165
}
147166

148167
TextureManager::~TextureManager()

0 commit comments

Comments
 (0)