diff --git a/src/libprojectM/Renderer/Makefile.am b/src/libprojectM/Renderer/Makefile.am index a15709946d..60a2c28205 100644 --- a/src/libprojectM/Renderer/Makefile.am +++ b/src/libprojectM/Renderer/Makefile.am @@ -15,6 +15,7 @@ libRenderer_la_SOURCES = \ Waveform.cpp \ Filters.cpp \ PerlinNoise.cpp \ + PerlinNoiseWithAlpha.cpp \ PipelineContext.cpp \ Renderable.cpp \ BeatDetect.cpp \ @@ -28,7 +29,7 @@ libRenderer_la_SOURCES = \ Filters.hpp RenderItemMatcher.hpp Transformation.hpp\ MilkdropWaveform.hpp RenderItemMergeFunction.hpp Texture.hpp\ PerPixelMesh.hpp Renderable.hpp VideoEcho.hpp\ - PerlinNoise.hpp Renderer.hpp Waveform.hpp\ + PerlinNoise.hpp PerlinNoiseWithAlpha.hpp Renderer.hpp Waveform.hpp\ Pipeline.hpp Shader.hpp\ SOIL2/SOIL2.h SOIL2/stbi_DDS.h\ SOIL2/etc1_utils.h SOIL2/stbi_DDS_c.h\ diff --git a/src/libprojectM/Renderer/PerlinNoiseWithAlpha.cpp b/src/libprojectM/Renderer/PerlinNoiseWithAlpha.cpp new file mode 100644 index 0000000000..93a92ce153 --- /dev/null +++ b/src/libprojectM/Renderer/PerlinNoiseWithAlpha.cpp @@ -0,0 +1,81 @@ +/* + * PerlinNoiseWithAlpha.cpp + * + * Created and based on PerlinNoise.hpp + * Created on: Sep 14, 2019 + * Author: hibengler + */ + +#include "PerlinNoiseWithAlpha.hpp" +#include +#include + +/* The reason for this cousin class is that in Open GLES 2.0 environments, +the glTexImage2d cannot convert from GL_RGB into GL_RGBA +so the TextureManager has to use something that is pre-RGBA +*/ +PerlinNoiseWithAlpha::PerlinNoiseWithAlpha() +{ + for (int x = 0; x < 256;x++) { + for (int y = 0; y < 256;y++) { + noise_lq[x][y][0] = noise(x , y); + noise_lq[x][y][1] = noise_lq[x][y][0]; + noise_lq[x][y][2] = noise_lq[x][y][0]; + noise_lq[x][y][3] = 1.f; + } + } + + for (int x = 0; x < 32;x++) { + for (int y = 0; y < 32;y++) { + noise_lq_lite[x][y][0] = noise(4*x,16*y); + noise_lq_lite[x][y][1] = noise_lq_lite[x][y][0]; + noise_lq_lite[x][y][2] = noise_lq_lite[x][y][0]; + noise_lq_lite[x][y][3] = 1.f; + } + } + + for (int x = 0; x < 256;x++) { + for (int y = 0; y < 256;y++) { + noise_mq[x][y][0] = InterpolatedNoise((float)x/(float)2.0,(float)y/(float)2.0); + noise_mq[x][y][1] = noise_mq[x][y][0]; + noise_mq[x][y][2] = noise_mq[x][y][0]; + noise_mq[x][y][3] = 1.f; + } + } + + for (int x = 0; x < 256;x++) { + for (int y = 0; y < 256;y++) { + noise_hq[x][y][0] = InterpolatedNoise((float)x/(float)3.0,(float)y/(float)3.0); + noise_hq[x][y][1] = noise_hq[x][y][0]; + noise_hq[x][y][2] = noise_hq[x][y][0]; + noise_hq[x][y][3] = 1.f; + } + } + + for (int x = 0; x < 32;x++) { + for (int y = 0; y < 32;y++) { + for (int z = 0; z < 32;z++) { + noise_lq_vol[x][y][z][0] = noise(x,y,z); + noise_lq_vol[x][y][z][1] = noise_lq_vol[x][y][z][0]; + noise_lq_vol[x][y][z][2] = noise_lq_vol[x][y][z][0]; + noise_lq_vol[x][y][z][3] = 1.f; + } + } + } + + for (int x = 0; x < 32;x++) { + for (int y = 0; y < 32;y++) { + for (int z = 0; z < 32;z++) { + noise_hq_vol[x][y][z][0] = noise(x,y,z); + noise_hq_vol[x][y][z][1] = noise_hq_vol[x][y][z][0]; + noise_hq_vol[x][y][z][2] = noise_hq_vol[x][y][z][0]; + noise_hq_vol[x][y][z][3] = 1.f; + } + } + } +} + +PerlinNoiseWithAlpha::~PerlinNoiseWithAlpha() +{ + // TODO Auto-generated destructor stub +} diff --git a/src/libprojectM/Renderer/PerlinNoiseWithAlpha.hpp b/src/libprojectM/Renderer/PerlinNoiseWithAlpha.hpp new file mode 100644 index 0000000000..92f3b123b3 --- /dev/null +++ b/src/libprojectM/Renderer/PerlinNoiseWithAlpha.hpp @@ -0,0 +1,176 @@ +/* + * PerlinNoise.hpp + * + * Created and based on PerlinNoise.hpp + * Created on: Sep 14, 2019 + * Author: hibengler + */ + + +/* The reason for this cousin class is that in Open GLES 2.0 environments, +the glTexImage2d cannot convert from GL_RGB into GL_RGBA +so the TextureManager has to use something that is pre-RGBA +*/ +#ifndef PERLINNOISEWITHALPHA_HPP_ +#define PERLINNOISEWITHALPHA_HPP_ + +#include + +class PerlinNoiseWithAlpha +{ +public: + + float noise_lq[256][256][4]; + float noise_lq_lite[32][32][4]; + float noise_mq[256][256][4]; + float noise_hq[256][256][4]; + float noise_lq_vol[32][32][32][4]; + float noise_hq_vol[32][32][32][4]; + + + PerlinNoiseWithAlpha(); + virtual ~PerlinNoiseWithAlpha(); + +private: + + static inline float noise( int x) + { + x = (x<<13)^x; + return (((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0); + } + + static inline float noise(int x, int y) + { + int n = x + y * 57; + return noise(n); + } + + static inline float noise(int x, int y, int z) + { + int n = x + y * 57 + z * 141; + return noise(n); + } + + static inline float cubic_interp(float v0, float v1, float v2, float v3, float x) + { + float P = (v3 - v2) - (v0 - v1); + float Q = (v0 - v1) - P; + float R = v2 - v0; + + return P*pow(x,3) + Q * pow(x,2) + R*x + v1; + } + + static inline float InterpolatedNoise(float x, float y) + { + int integer_X = int(x); + float fractional_X = x - integer_X; + + int integer_Y = int(y); + float fractional_Y = y - integer_Y; + + float a0 = noise(integer_X - 1, integer_Y - 1); + float a1 = noise(integer_X, integer_Y - 1); + float a2 = noise(integer_X + 1, integer_Y - 1); + float a3 = noise(integer_X + 2, integer_Y - 1); + + float x0 = noise(integer_X - 1, integer_Y); + float x1 = noise(integer_X, integer_Y); + float x2 = noise(integer_X + 1, integer_Y); + float x3 = noise(integer_X + 2, integer_Y); + + float y0 = noise(integer_X + 0, integer_Y + 1); + float y1 = noise(integer_X, integer_Y + 1); + float y2 = noise(integer_X + 1, integer_Y + 1); + float y3 = noise(integer_X + 2, integer_Y + 1); + + float b0 = noise(integer_X - 1, integer_Y + 2); + float b1 = noise(integer_X, integer_Y + 2); + float b2 = noise(integer_X + 1, integer_Y + 2); + float b3 = noise(integer_X + 2, integer_Y + 2); + + float i0 = cubic_interp(a0 , a1, a2, a3, fractional_X); + float i1 = cubic_interp(x0 , x1, x2, x3, fractional_X); + float i2 = cubic_interp(y0 , y1, y2, y3, fractional_X); + float i3 = cubic_interp(b0 , b1, b2, b3, fractional_X); + + return cubic_interp(i0, i1 , i2 , i3, fractional_Y); + + } + + static inline float perlin_octave_3d(float x,float y, float z,int width, int seed, float period) + { + float freq=1/(float)(period); + + int num=(int)(width*freq); + int step_x=(int)(x*freq); + int step_y=(int)(y*freq); + int step_z=(int)(z*freq); + float zone_x=x*freq-step_x; + float zone_y=y*freq-step_y; + float zone_z=z*freq-step_z; + + int boxB=step_x+step_y+step_z*num; + int boxC=step_x+step_y+step_z*(num+1); + int boxD=step_x+step_y+step_z*(num+2); + int boxA=step_x+step_y+step_z*(num-1); + + float u,a,b,v,noisedata,box; + + box = boxA; + noisedata=(box+seed); + u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); + a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); + b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); + v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); + float A=cubic_interp(u,a,b,v,zone_y); + + box = boxB; + noisedata=(box+seed); + u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); + a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); + b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); + v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); + float B=cubic_interp(u,a,b,v,zone_y); + + box = boxC; + noisedata=(box+seed); + u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); + a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); + b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); + v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); + float C=cubic_interp(u,a,b,v,zone_y); + + box = boxD; + noisedata=(box+seed); + u=cubic_interp(noise(noisedata-num-1),noise(noisedata-num),noise(noisedata-num+1),noise(noisedata-num+2),zone_x); + a=cubic_interp(noise(noisedata-1),noise(noisedata),noise(noisedata+1),noise(noisedata+2),zone_x); + b=cubic_interp(noise(noisedata+num -1),noise(noisedata+num),noise(noisedata+1+num),noise(noisedata+2+num),zone_x); + v=cubic_interp(noise(noisedata+2*num -1),noise(noisedata+2*num),noise(noisedata+1+2*num),noise(noisedata+2+2*num),zone_x); + float D=cubic_interp(u,a,b,v,zone_y); + + float value =cubic_interp(A,B,C,D,zone_z); + + return value; + } + + + static inline float perlin_noise_3d(int x, int y, int z, int width, int octaves, int seed, float persistance, float basePeriod) + { + float p = persistance; + float val = 0.0; + + for (int i = 0; ishowstats = false; this->studio = false; this->realfps = 0; - /* Set up the v xoffset and vy offset to 0 which is normal Only used for VR */ this->vstartx = 0; this->vstarty = 0; @@ -169,7 +167,6 @@ Renderer::Renderer(int width, int height, int gx, int gy, BeatDetect *_beatDetec glBindBuffer(GL_ARRAY_BUFFER, 0); - // CompositeShaderOutput VAO/VBO's glGenBuffers(1, &m_vbo_CompositeShaderOutput); glGenVertexArrays(1, &m_vao_CompositeShaderOutput); diff --git a/src/libprojectM/Renderer/TextureManager.cpp b/src/libprojectM/Renderer/TextureManager.cpp index 87b8799d00..9f4ab41f97 100644 --- a/src/libprojectM/Renderer/TextureManager.cpp +++ b/src/libprojectM/Renderer/TextureManager.cpp @@ -24,9 +24,22 @@ #include "Common.hpp" #include "IdleTextures.hpp" #include "Texture.hpp" -#include "PerlinNoise.hpp" +/* OpenGL ES 2.0 cant handle converting textures fro GL_RGB to GL_RGBA via glTexImage2D +http://docs.gl/es2/glTexImage2D + +This causes a GLError INVALID_OPERATION(0x502) whenever making a new Renderer or resizing it. +So because of this, we switch to a PerlinNoiseWithAlpha class to generate the noise textures. +*/ +#ifdef GL_ES_VERSION_2_0 +#include "PerlinNoiseWithAlpha.hpp" +#define NOISE_INTERNAL_DATA_FORMAT GL_RGBA +#else +#include "PerlinNoise.hpp" +#define NOISE_INTERNAL_DATA_FORMAT GL_RGB +#endif + #define NUM_BLUR_TEX 6 @@ -94,12 +107,16 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX blurTextures.push_back(textureBlur); } +#ifdef GL_ES_VERSION_2_0 + std::unique_ptr noise(new PerlinNoiseWithAlpha()); +#else std::unique_ptr noise(new PerlinNoise()); +#endif GLuint noise_texture_lq_lite; glGenTextures(1, &noise_texture_lq_lite); glBindTexture(GL_TEXTURE_2D, noise_texture_lq_lite); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGB, GL_FLOAT, noise->noise_lq_lite); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_lq_lite); Texture * textureNoise_lq_lite = new Texture("noise_lq_lite", noise_texture_lq_lite, GL_TEXTURE_2D, 32, 32, false); textureNoise_lq_lite->getSampler(GL_REPEAT, GL_LINEAR); textures["noise_lq_lite"] = textureNoise_lq_lite; @@ -107,7 +124,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX GLuint noise_texture_lq; glGenTextures(1, &noise_texture_lq); glBindTexture(GL_TEXTURE_2D, noise_texture_lq); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_lq); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_lq); Texture * textureNoise_lq = new Texture("noise_lq", noise_texture_lq, GL_TEXTURE_2D, 256, 256, false); textureNoise_lq->getSampler(GL_REPEAT, GL_LINEAR); textures["noise_lq"] = textureNoise_lq; @@ -115,7 +132,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX GLuint noise_texture_mq; glGenTextures(1, &noise_texture_mq); glBindTexture(GL_TEXTURE_2D, noise_texture_mq); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_mq); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_mq); Texture * textureNoise_mq = new Texture("noise_mq", noise_texture_mq, GL_TEXTURE_2D, 256, 256, false); textureNoise_mq->getSampler(GL_REPEAT, GL_LINEAR); textures["noise_mq"] = textureNoise_mq; @@ -123,7 +140,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX GLuint noise_texture_hq; glGenTextures(1, &noise_texture_hq); glBindTexture(GL_TEXTURE_2D, noise_texture_hq); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_FLOAT, noise->noise_hq); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_hq); Texture * textureNoise_hq = new Texture("noise_hq", noise_texture_hq, GL_TEXTURE_2D, 256, 256, false); textureNoise_hq->getSampler(GL_REPEAT, GL_LINEAR); textures["noise_hq"] = textureNoise_hq; @@ -131,7 +148,7 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX GLuint noise_texture_lq_vol; glGenTextures( 1, &noise_texture_lq_vol ); glBindTexture( GL_TEXTURE_3D, noise_texture_lq_vol ); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,GL_RGB ,GL_FLOAT ,noise->noise_lq_vol); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32 ,32 ,32 ,0 ,NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT ,noise->noise_lq_vol); Texture * textureNoise_lq_vol = new Texture("noisevol_lq", noise_texture_lq_vol, GL_TEXTURE_3D, 32, 32, false); textureNoise_lq_vol->getSampler(GL_REPEAT, GL_LINEAR); textures["noisevol_lq"] = textureNoise_lq_vol; @@ -139,10 +156,12 @@ TextureManager::TextureManager(const std::string _presetsURL, const int texsizeX GLuint noise_texture_hq_vol; glGenTextures( 1, &noise_texture_hq_vol ); glBindTexture( GL_TEXTURE_3D, noise_texture_hq_vol ); - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, GL_RGB, GL_FLOAT, noise->noise_hq_vol); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, 0, NOISE_INTERNAL_DATA_FORMAT, GL_FLOAT, noise->noise_hq_vol); + Texture * textureNoise_hq_vol = new Texture("noisevol_hq", noise_texture_hq_vol, GL_TEXTURE_3D, 32, 32, false); textureNoise_hq_vol->getSampler(GL_REPEAT, GL_LINEAR); textures["noisevol_hq"] = textureNoise_hq_vol; + } TextureManager::~TextureManager() diff --git a/src/libprojectM/TimeKeeper.cpp b/src/libprojectM/TimeKeeper.cpp index f497fc0863..cb0b6996a8 100644 --- a/src/libprojectM/TimeKeeper.cpp +++ b/src/libprojectM/TimeKeeper.cpp @@ -14,7 +14,7 @@ TimeKeeper::TimeKeeper(double presetDuration, double smoothDuration, double east _easterEgg = easterEgg; #ifndef WIN32 - gettimeofday ( &this->startTime, NULL ); + projectm_gettimeofday ( &this->startTime, NULL ); #else startTime = GetTickCount(); #endif /** !WIN32 */ diff --git a/src/libprojectM/projectM.hpp b/src/libprojectM/projectM.hpp old mode 100755 new mode 100644 index 11319e4584..2f6206c40b --- a/src/libprojectM/projectM.hpp +++ b/src/libprojectM/projectM.hpp @@ -53,7 +53,7 @@ #endif /** WIN32 */ #endif /** MACOS */ -#ifdef WIN322 +#ifdef WIN32 #define inline #endif /** WIN32 */ diff --git a/src/libprojectM/timer.cpp b/src/libprojectM/timer.cpp old mode 100755 new mode 100644 index c347e1ea14..c91ef1daaf --- a/src/libprojectM/timer.cpp +++ b/src/libprojectM/timer.cpp @@ -23,26 +23,50 @@ * * Platform-independent timer */ - +#include #include "timer.h" #include + #ifndef WIN32 /** Get number of ticks since the given timestamp */ + + +extern "C" { + +fspec_gettimeofday pprojectm_gettimeofday = nullptr; + +int projectm_gettimeofday(struct timeval *tv, struct timezone *tz) { +if (pprojectm_gettimeofday) { + return (*pprojectm_gettimeofday)(tv,tz); + } +return gettimeofday(tv,tz); +} +} + +struct timeval GetCurrentTime() { + struct timeval now; + + projectm_gettimeofday(&now, NULL); + return now; + } + unsigned int getTicks( struct timeval *start ) { struct timeval now; unsigned int ticks; - gettimeofday(&now, NULL); + projectm_gettimeofday(&now, NULL); ticks=(now.tv_sec-start->tv_sec)*1000+(now.tv_usec-start->tv_usec)/1000; return(ticks); } #else + unsigned int getTicks( long start ) { return GetTickCount() - start; } + #endif /** !WIN32 */ diff --git a/src/libprojectM/timer.h b/src/libprojectM/timer.h old mode 100755 new mode 100644 index 2cc4ae49aa..e1315d65f5 --- a/src/libprojectM/timer.h +++ b/src/libprojectM/timer.h @@ -38,9 +38,22 @@ #ifndef _TIMER_H #define _TIMER_H + + #ifndef WIN32 #include unsigned int getTicks( struct timeval *start ); + +extern "C" { +typedef int (*fspec_gettimeofday)(struct timeval *tv, struct timezone *tz); +int projectm_gettimeofday(struct timeval *tv, struct timezone *tz); +extern fspec_gettimeofday pprojectm_gettimeofday; + +} + + + + struct timeval GetCurrentTime(); #else #include diff --git a/src/projectM-sdl/projectM_SDL_main.cpp b/src/projectM-sdl/projectM_SDL_main.cpp index 456f41252d..769132ceb6 100644 --- a/src/projectM-sdl/projectM_SDL_main.cpp +++ b/src/projectM-sdl/projectM_SDL_main.cpp @@ -109,6 +109,9 @@ HRESULT get_default_device(IMMDevice **ppMMDevice) { #endif /** WASAPI_LOOPBACK */ int main(int argc, char *argv[]) { +#ifndef WIN32 +srand((int)(time(NULL))); +#endif #ifdef WASAPI_LOOPBACK HRESULT hr;