mirror of
https://github.com/projectM-visualizer/projectm.git
synced 2026-03-29 18:54:07 +00:00
MilkdropWaveform added and tested as little as possible
git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@1060 6778bc44-b910-0410-a7a0-be141de4315d
This commit is contained in:
@ -31,7 +31,8 @@ SET(projectM_SOURCES projectM.cpp FBO.cpp InitCond.cpp
|
||||
Func.cpp Eval.cpp PerFrameEqn.cpp PerPointEqn.cpp fftsg.cpp KeyHandler.cpp
|
||||
timer.cpp wipemalloc.cpp BuiltinFuncs.cpp BuiltinParams.cpp Renderer.cpp
|
||||
PresetLoader.cpp PresetChooser.cpp PresetFrameIO.cpp PresetMerge.cpp PipelineContext.cpp
|
||||
ConfigFile.cpp IdlePreset.cpp TextureManager.cpp TimeKeeper.cpp Filters.cpp Renderable.cpp Pipeline.cpp PerPixelMesh.cpp ${GLEW_SOURCES})
|
||||
ConfigFile.cpp IdlePreset.cpp TextureManager.cpp TimeKeeper.cpp Filters.cpp Renderable.cpp Pipeline.cpp PerPixelMesh.cpp
|
||||
MilkdropWaveform.cpp ${GLEW_SOURCES})
|
||||
|
||||
if (USE_DEVIL)
|
||||
SET (projectM_SOURCES ${projectM_SOURCES})
|
||||
|
||||
358
src/projectM-engine/MilkdropWaveform.cpp
Normal file
358
src/projectM-engine/MilkdropWaveform.cpp
Normal file
@ -0,0 +1,358 @@
|
||||
/*
|
||||
* MilkdropWaveform.cpp
|
||||
*
|
||||
* Created on: Jun 25, 2008
|
||||
* Author: pete
|
||||
*/
|
||||
|
||||
|
||||
#include "MilkdropWaveform.hpp"
|
||||
#include "math.h"
|
||||
|
||||
MilkdropWaveform::MilkdropWaveform()
|
||||
: x(0.5), y(0.5), r(1), g(0), b(0), a(1), mystery(0), mode(Line), scale(10), smoothing(0), rot(0), samples(0),modOpacityStart(0),modOpacityEnd(1),
|
||||
modulateAlphaByVolume(false), maximizeColors(false), additive(false), dots(false), thick(false), loop(false) {}
|
||||
|
||||
void MilkdropWaveform::Draw(RenderContext &context)
|
||||
{
|
||||
WaveformMath(context);
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
if(modulateAlphaByVolume) ModulateOpacityByVolume(context);
|
||||
MaximizeColors(context);
|
||||
|
||||
#ifndef USE_GLES1
|
||||
if(dots==1) glEnable(GL_LINE_STIPPLE);
|
||||
#endif
|
||||
|
||||
//Thick wave drawing
|
||||
if (thick==1) glLineWidth( (context.texsize < 512 ) ? 2 : 2*context.texsize/512);
|
||||
else glLineWidth( (context.texsize < 512 ) ? 1 : context.texsize/512);
|
||||
|
||||
//Additive wave drawing (vice overwrite)
|
||||
if (additive==0) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
glTranslatef(.5, .5, 0);
|
||||
glRotatef(rot, 0, 0, 1);
|
||||
glScalef(aspectScale, 1.0, 1.0);
|
||||
glTranslatef(-.5, -.5, 0);
|
||||
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glVertexPointer(2,GL_FLOAT,0,wavearray);
|
||||
|
||||
if (loop)
|
||||
glDrawArrays(GL_LINE_LOOP,0,samples);
|
||||
else
|
||||
glDrawArrays(GL_LINE_STRIP,0,samples);
|
||||
|
||||
|
||||
if (two_waves)
|
||||
{
|
||||
glVertexPointer(2,GL_FLOAT,0,wavearray2);
|
||||
if (loop)
|
||||
glDrawArrays(GL_LINE_LOOP,0,samples);
|
||||
else
|
||||
glDrawArrays(GL_LINE_STRIP,0,samples);
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_GLES1
|
||||
if(dots==1) glDisable(GL_LINE_STIPPLE);
|
||||
#endif
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
void MilkdropWaveform::ModulateOpacityByVolume(RenderContext &context)
|
||||
{
|
||||
|
||||
//modulate volume by opacity
|
||||
//
|
||||
//set an upper and lower bound and linearly
|
||||
//calculate the opacity from 0=lower to 1=upper
|
||||
//based on current volume
|
||||
|
||||
if (context.beatDetect->vol<= modOpacityStart) a=0.0;
|
||||
else if (context.beatDetect->vol>=modOpacityEnd) a=a;
|
||||
else a*=((context.beatDetect->vol-modOpacityStart)/(modOpacityEnd-modOpacityStart));
|
||||
|
||||
}
|
||||
|
||||
void MilkdropWaveform::MaximizeColors(RenderContext &context)
|
||||
{
|
||||
|
||||
float wave_r_switch=0, wave_g_switch=0, wave_b_switch=0;
|
||||
//wave color brightening
|
||||
//
|
||||
//forces max color value to 1.0 and scales
|
||||
// the rest accordingly
|
||||
if(mode==Blob2 || mode==Blob5)
|
||||
switch(context.texsize)
|
||||
{
|
||||
case 256: a *= 0.07f; break;
|
||||
case 512: a *= 0.09f; break;
|
||||
case 1024: a *= 0.11f; break;
|
||||
case 2048: a *= 0.13f; break;
|
||||
}
|
||||
else if(mode==Blob3)
|
||||
{
|
||||
switch(context.texsize)
|
||||
{
|
||||
case 256: a *= 0.075f; break;
|
||||
case 512: a *= 0.15f; break;
|
||||
case 1024: a *= 0.22f; break;
|
||||
case 2048: a *= 0.33f; break;
|
||||
}
|
||||
a*=1.3f;
|
||||
a*=powf(context.beatDetect->treb , 2.0f);
|
||||
}
|
||||
|
||||
if (maximizeColors==true)
|
||||
{
|
||||
if(r>=g && r>=b) //red brightest
|
||||
{
|
||||
wave_b_switch=b*(1/r);
|
||||
wave_g_switch=g*(1/r);
|
||||
wave_r_switch=1.0;
|
||||
}
|
||||
else if (b>=g && b>=r) //blue brightest
|
||||
{
|
||||
wave_r_switch=r*(1/b);
|
||||
wave_g_switch=g*(1/b);
|
||||
wave_b_switch=1.0;
|
||||
|
||||
}
|
||||
|
||||
else if (g>=b && g>=r) //green brightest
|
||||
{
|
||||
wave_b_switch=b*(1/g);
|
||||
wave_r_switch=r*(1/g);
|
||||
wave_g_switch=1.0;
|
||||
}
|
||||
|
||||
|
||||
glColor4f(wave_r_switch, wave_g_switch, wave_b_switch, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4f(r, g, b, a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MilkdropWaveform::WaveformMath(RenderContext &context)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
float r, theta;
|
||||
|
||||
float offset;
|
||||
|
||||
float wave_x_temp=0;
|
||||
float wave_y_temp=0;
|
||||
|
||||
float cos_rot;
|
||||
float sin_rot;
|
||||
|
||||
offset=x-.5;
|
||||
float temp_y;
|
||||
|
||||
two_waves = false;
|
||||
loop = false;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
|
||||
case RadialBlob:
|
||||
{
|
||||
loop = true;
|
||||
rot = 0;
|
||||
aspectScale=1.0;
|
||||
temp_y=-1*(y-1.0);
|
||||
|
||||
|
||||
samples = 0? 512-32 : context.beatDetect->pcm->numsamples;
|
||||
|
||||
float inv_nverts_minus_one = 1.0f/(float)(samples);
|
||||
|
||||
float last_value = context.beatDetect->pcm->pcmdataR[samples-1]+context.beatDetect->pcm->pcmdataL[samples-1];
|
||||
float first_value = context.beatDetect->pcm->pcmdataR[0]+context.beatDetect->pcm->pcmdataL[0];
|
||||
float offset = first_value-last_value;
|
||||
|
||||
for ( int i=0;i<samples;i++)
|
||||
{
|
||||
|
||||
float value = context.beatDetect->pcm->pcmdataR[i]+context.beatDetect->pcm->pcmdataL[i];
|
||||
value += offset * (x/(float)samples);
|
||||
|
||||
r=(0.5 + 0.4f*.12*value*scale + mystery)*.5;
|
||||
theta=(x)*inv_nverts_minus_one*6.28f + context.time*0.2f;
|
||||
|
||||
wavearray[i][0]=(r*cos(theta)*(context.aspectCorrect? context.aspectRatio : 1.0)+x);
|
||||
wavearray[i][1]=(r*sin(theta)+temp_y);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1://circularly moving waveform
|
||||
|
||||
rot = 0;
|
||||
aspectScale = context.aspectRatio;
|
||||
|
||||
temp_y=-1*(y-1.0);
|
||||
|
||||
samples = 512-32;
|
||||
for ( int i=0;i<512-32;i++)
|
||||
{
|
||||
theta=context.beatDetect->pcm->pcmdataL[i+32]*0.06*scale * 1.57 + context.time*2.3;
|
||||
r=(0.53 + 0.43*context.beatDetect->pcm->pcmdataR[i]*0.12*scale+ mystery)*.5;
|
||||
|
||||
wavearray[i][0]=(r*cos(theta)*(context.aspectCorrect ? context.aspectRatio : 1.0)+i);
|
||||
wavearray[i][1]=(r*sin(theta)+temp_y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Blob2://EXPERIMENTAL
|
||||
|
||||
temp_y=-1*(y-1.0);
|
||||
rot = 0;
|
||||
aspectScale =1.0;
|
||||
samples = 512-32;
|
||||
|
||||
for ( int i=0;i<512-32;i++)
|
||||
{
|
||||
wavearray[i][0]=(context.beatDetect->pcm->pcmdataR[i]*scale*0.5*(context.aspectCorrect ? context.aspectRatio : 1.0) + x);
|
||||
wavearray[i][1]=(context.beatDetect->pcm->pcmdataL[i+32]*scale*0.5 + temp_y);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Blob3://EXPERIMENTAL
|
||||
|
||||
temp_y=-1*(y-1.0);
|
||||
|
||||
rot = 0;
|
||||
aspectScale =1.0;
|
||||
|
||||
samples = 512-32;
|
||||
|
||||
for ( int i=0;i<512-32;i++)
|
||||
{
|
||||
wavearray[i][0]=(context.beatDetect->pcm->pcmdataR[i] * scale*0.5 + x);
|
||||
wavearray[i][1]=( (context.beatDetect->pcm->pcmdataL[i+32]*scale*0.5 + temp_y));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DerivativeLine://single x-axis derivative waveform
|
||||
{
|
||||
rot =-mystery*90;
|
||||
aspectScale=1.0;
|
||||
|
||||
temp_y=-1*(y-1.0);
|
||||
|
||||
float w1 = 0.45f + 0.5f*(mystery*0.5f + 0.5f);
|
||||
float w2 = 1.0f - w1;
|
||||
float xx[512], yy[512];
|
||||
samples = 512-32;
|
||||
|
||||
for (int i=0; i<512-32; i++)
|
||||
{
|
||||
xx[i] = -1.0f + 2.0f*(i/(512.0-32.0)) + x;
|
||||
yy[i] =0.4* context.beatDetect->pcm->pcmdataL[i]*0.47f*scale + temp_y;
|
||||
xx[i] += 0.4*context.beatDetect->pcm->pcmdataR[i]*0.44f*scale;
|
||||
|
||||
if (i>1)
|
||||
{
|
||||
xx[i] = xx[i]*w2 + w1*(xx[i-1]*2.0f - xx[i-2]);
|
||||
yy[i] = yy[i]*w2 + w1*(yy[i-1]*2.0f - yy[i-2]);
|
||||
}
|
||||
wavearray[i][0]=xx[i];
|
||||
wavearray[i][1]=yy[i];
|
||||
} }
|
||||
break;
|
||||
|
||||
case Blob5://EXPERIMENTAL
|
||||
|
||||
rot = 0;
|
||||
aspectScale =1.0;
|
||||
|
||||
temp_y=-1*(y-1.0);
|
||||
|
||||
cos_rot = cosf(context.time*0.3f);
|
||||
sin_rot = sinf(context.time*0.3f);
|
||||
samples = 512-32;
|
||||
|
||||
for ( int i=0;i<512-32;i++)
|
||||
{
|
||||
float x0 = (context.beatDetect->pcm->pcmdataR[i]*context.beatDetect->pcm->pcmdataL[i+32] + context.beatDetect->pcm->pcmdataL[i+32]*context.beatDetect->pcm->pcmdataR[i]);
|
||||
float y0 = (context.beatDetect->pcm->pcmdataR[i]*context.beatDetect->pcm->pcmdataR[i] - context.beatDetect->pcm->pcmdataL[i+32]*context.beatDetect->pcm->pcmdataL[i+32]);
|
||||
wavearray[i][0]=((x0*cos_rot - y0*sin_rot)*scale*0.5*(context.aspectCorrect ? context.aspectRatio : 1.0) + x);
|
||||
wavearray[i][1]=( (x0*sin_rot + y0*cos_rot)*scale*0.5 + temp_y);
|
||||
}
|
||||
break;
|
||||
|
||||
case Line://single waveform
|
||||
|
||||
|
||||
wave_x_temp=-2*0.4142*(fabs(fabs(mystery)-.5)-.5);
|
||||
|
||||
rot = -mystery*90;
|
||||
aspectScale =1.0+wave_x_temp;
|
||||
wave_x_temp=-1*(x-1.0);
|
||||
samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples;
|
||||
|
||||
for ( int i=0;i< samples;i++)
|
||||
{
|
||||
|
||||
wavearray[i][0]=i/(float) samples;
|
||||
wavearray[i][1]=context.beatDetect->pcm->pcmdataR[i]*.04*scale+wave_x_temp;
|
||||
|
||||
}
|
||||
// printf("%f %f\n",renderTarget->texsize*wave_y_temp,wave_y_temp);
|
||||
|
||||
break;
|
||||
|
||||
case DoubleLine://dual waveforms
|
||||
|
||||
|
||||
wave_x_temp=-2*0.4142*(fabs(fabs(mystery)-.5)-.5);
|
||||
|
||||
rot = -mystery*90;
|
||||
aspectScale =1.0+wave_x_temp;
|
||||
|
||||
|
||||
samples = 0 ? 512-32 : context.beatDetect->pcm->numsamples;
|
||||
two_waves = true;
|
||||
|
||||
double y_adj = y*y*.5;
|
||||
|
||||
wave_y_temp=-1*(x-1);
|
||||
|
||||
for ( int i=0;i<samples;i++)
|
||||
{
|
||||
wavearray[i][0]=x/((float) samples);
|
||||
wavearray[i][1]= context.beatDetect->pcm->pcmdataL[i]*.04*scale+(wave_y_temp+y_adj);
|
||||
}
|
||||
|
||||
for ( int i=0;i<samples;i++)
|
||||
{
|
||||
wavearray2[i][0]=x/((float) samples);
|
||||
wavearray2[i][1]=context.beatDetect->pcm->pcmdataR[i]*.04*scale+(wave_y_temp-y_adj);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
62
src/projectM-engine/MilkdropWaveform.hpp
Normal file
62
src/projectM-engine/MilkdropWaveform.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* MilkdropWaveform.hpp
|
||||
*
|
||||
* Created on: Jun 25, 2008
|
||||
* Author: pete
|
||||
*/
|
||||
|
||||
#ifndef MILKDROPWAVEFORM_HPP_
|
||||
#define MILKDROPWAVEFORM_HPP_
|
||||
|
||||
#include "Renderable.hpp"
|
||||
|
||||
class MilkdropWaveform : public RenderItem
|
||||
{
|
||||
public:
|
||||
|
||||
enum MilkdropWaveformMode
|
||||
{
|
||||
RadialBlob, Circle, Blob2, Blob3, DerivativeLine, Blob5, Line, DoubleLine
|
||||
};
|
||||
|
||||
float x;
|
||||
float y;
|
||||
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
|
||||
float mystery;
|
||||
|
||||
MilkdropWaveformMode mode;
|
||||
|
||||
bool additive;
|
||||
bool dots;
|
||||
bool thick;
|
||||
bool modulateAlphaByVolume;
|
||||
bool maximizeColors;
|
||||
float scale;
|
||||
float smoothing;
|
||||
|
||||
MilkdropWaveform();
|
||||
void Draw(RenderContext &context);
|
||||
|
||||
float modOpacityStart;
|
||||
float modOpacityEnd;
|
||||
|
||||
private:
|
||||
float rot;
|
||||
float aspectScale;
|
||||
int samples;
|
||||
bool two_waves;
|
||||
bool loop;
|
||||
float wavearray[2048][2];
|
||||
float wavearray2[2048][2];
|
||||
|
||||
void MaximizeColors(RenderContext &context);
|
||||
void ModulateOpacityByVolume(RenderContext &context);
|
||||
void WaveformMath(RenderContext &context);
|
||||
|
||||
};
|
||||
#endif /* MILKDROPWAVEFORM_HPP_ */
|
||||
@ -16,7 +16,8 @@
|
||||
#include <math.h>
|
||||
|
||||
RenderContext::RenderContext()
|
||||
:texsize(512), aspectRatio(1), aspectCorrect(false){};
|
||||
: time(0),texsize(512), aspectRatio(1), aspectCorrect(false){};
|
||||
|
||||
|
||||
Shape::Shape()
|
||||
{
|
||||
@ -73,7 +74,7 @@ void Shape::Draw(RenderContext &context)
|
||||
{
|
||||
if (imageUrl !="")
|
||||
{
|
||||
GLuint tex = textureManager->getTexture(imageUrl);
|
||||
GLuint tex = context.textureManager->getTexture(imageUrl);
|
||||
if (tex != 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
@ -3,13 +3,17 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "TextureManager.hpp"
|
||||
#include "BeatDetect.hpp"
|
||||
|
||||
class RenderContext
|
||||
{
|
||||
public:
|
||||
float time;
|
||||
int texsize;
|
||||
float aspectRatio;
|
||||
bool aspectCorrect;
|
||||
BeatDetect *beatDetect;
|
||||
TextureManager *textureManager;
|
||||
|
||||
RenderContext();
|
||||
};
|
||||
@ -20,13 +24,7 @@ public:
|
||||
virtual void Draw(RenderContext &context) = 0;
|
||||
};
|
||||
|
||||
class TexturedItem
|
||||
{
|
||||
public:
|
||||
TextureManager *textureManager;
|
||||
};
|
||||
|
||||
class Shape : public TexturedItem, public RenderItem
|
||||
class Shape : public RenderItem
|
||||
{
|
||||
public:
|
||||
std::string imageUrl;
|
||||
|
||||
@ -134,7 +134,7 @@ myCgContext = cgCreateContext();
|
||||
cgGLSetDebugMode( CG_FALSE );
|
||||
cgSetParameterSettingMode(myCgContext, CG_DEFERRED_PARAMETER_SETTING);
|
||||
|
||||
|
||||
|
||||
myCgProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||
cgGLSetOptimalOptions(myCgProfile);
|
||||
checkForCgError("selecting fragment profile");
|
||||
@ -151,7 +151,7 @@ myCgContext = cgCreateContext();
|
||||
cgGLLoadProgram(myCgWarpProgram);
|
||||
checkForCgError("loading fragment program");
|
||||
|
||||
|
||||
|
||||
|
||||
myCgCompositeProgram =
|
||||
cgCreateProgramFromFile(
|
||||
@ -181,7 +181,7 @@ void Renderer::ResetTextures()
|
||||
textureManager->Preload();
|
||||
}
|
||||
|
||||
void Renderer::RenderFrame(const Pipeline* pipeline)
|
||||
void Renderer::RenderFrame(const Pipeline* pipeline, const PipelineContext &pipelineContext)
|
||||
{
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@ -233,9 +233,12 @@ void Renderer::RenderFrame(const Pipeline* pipeline)
|
||||
checkForCgError("disabling fragment profile");
|
||||
#endif
|
||||
|
||||
renderContext.time = pipelineContext.time;
|
||||
renderContext.texsize = texsize;
|
||||
renderContext.aspectCorrect = correction;
|
||||
renderContext.aspectRatio = aspect;
|
||||
renderContext.textureManager = textureManager;
|
||||
renderContext.beatDetect = beatDetect;
|
||||
|
||||
for (std::vector<RenderItem*>::const_iterator pos = pipeline->drawables.begin(); pos != pipeline->drawables.end(); ++pos)
|
||||
(*pos)->Draw(renderContext);
|
||||
@ -583,10 +586,7 @@ void Renderer::Interpolation(const Pipeline *pipeline)
|
||||
|
||||
}
|
||||
Pipeline* Renderer::currentPipe;
|
||||
Point Renderer::PerPixel(Point p, PerPixelContext context)
|
||||
{
|
||||
return currentPipe->PerPixel(p,context);
|
||||
}
|
||||
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
|
||||
@ -71,7 +71,7 @@ public:
|
||||
Renderer( int width, int height, int gx, int gy, int texsize, BeatDetect *beatDetect, std::string presetURL, std::string title_fontURL, std::string menu_fontURL);
|
||||
~Renderer();
|
||||
void RenderFrame(PresetOutputs *presetOutputs, PresetInputs *presetInputs);
|
||||
void RenderFrame(const Pipeline *pipeline);
|
||||
void RenderFrame(const Pipeline *pipeline, const PipelineContext &pipelineContext);
|
||||
void ResetTextures();
|
||||
void reset(int w, int h);
|
||||
GLuint initRenderToTexture();
|
||||
@ -117,7 +117,7 @@ private:
|
||||
|
||||
CGcontext myCgContext;
|
||||
CGprofile myCgProfile;
|
||||
|
||||
|
||||
CGprogram myCgWarpProgram,
|
||||
myCgCompositeProgram;
|
||||
|
||||
@ -145,8 +145,10 @@ void SetupCg();
|
||||
|
||||
void CompositeOutput(const Pipeline* pipeline);
|
||||
void Interpolation(const Pipeline* pipeline);
|
||||
static Point PerPixel(Point p, PerPixelContext context);
|
||||
|
||||
inline static Point PerPixel(Point p, PerPixelContext &context)
|
||||
{
|
||||
return currentPipe->PerPixel(p,context);
|
||||
}
|
||||
|
||||
void Interpolation(PresetOutputs *presetOutputs, PresetInputs *presetInputs);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user