📄 gpufftw.cpp
字号:
double pi= 3.14159265358979323846;
void GPUFFTW::cgpufft1d( float sign, int usedfor2dfft ){
int i,j,z;
//Go into FBO mode, bind the uploaded data as the source texture
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glDrawBuffer( GL_COLOR_ATTACHMENT0_EXT);
glColorMask(~0,~0,~0,~0);
glEnable(GL_TEXTURE_RECTANGLE_NV);
glActiveTextureARB( GL_TEXTURE2_ARB );
glBindTexture(GL_TEXTURE_RECTANGLE_NV, textureid[1]);
glActiveTextureARB( GL_TEXTURE3_ARB );
glBindTexture(GL_TEXTURE_RECTANGLE_NV, textureid[3]);
source=0;
target=1;
//the first two stages are special stages since the FFT is performed on chunks of size 4
glActiveTextureARB( GL_TEXTURE2_ARB );
PingPong();
fullscreenfft1ststage.Bind();
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 0,0);
glMultiTexCoord2f(GL_TEXTURE1, 0,Height/2);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glVertex2f(0,0);
glMultiTexCoord2f(GL_TEXTURE0,Width/2,0);
glMultiTexCoord2f(GL_TEXTURE1, Width/2,Height/2);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glVertex2f(Width,0);
glMultiTexCoord2f(GL_TEXTURE0,Width/2,Height/2);
glMultiTexCoord2f(GL_TEXTURE1, Width/2,Height);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glVertex2f(Width,Height);
glMultiTexCoord2f(GL_TEXTURE0,0,Height/2);
glMultiTexCoord2f(GL_TEXTURE1, 0,Height);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glVertex2f(0,Height);
glEnd();
PingPong();
fullscreenfft2ndstagefp.BindProg();
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 0,0);
glMultiTexCoord2f(GL_TEXTURE1, 0,Height/2);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glMultiTexCoord2f(GL_TEXTURE3, 1,cos(-sign*2*pi/(4.0)));
glMultiTexCoord2f(GL_TEXTURE4, 0,sin(-sign*2*pi/(4.0)));
glVertex2f(0,0);
glMultiTexCoord2f(GL_TEXTURE0,Width/2,0);
glMultiTexCoord2f(GL_TEXTURE1, Width/2,Height/2);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glMultiTexCoord2f(GL_TEXTURE3, 1,cos(-sign*2*pi/(4.0)));
glMultiTexCoord2f(GL_TEXTURE4, 0,sin(-sign*2*pi/(4.0)));
glVertex2f(Width,0);
glMultiTexCoord2f(GL_TEXTURE0,Width/2,Height/2);
glMultiTexCoord2f(GL_TEXTURE1, Width/2,Height);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glMultiTexCoord2f(GL_TEXTURE3, 1,cos(-sign*2*pi/(4.0)));
glMultiTexCoord2f(GL_TEXTURE4, 0,sin(-sign*2*pi/(4.0)));
glVertex2f(Width,Height);
glMultiTexCoord2f(GL_TEXTURE0,0,Height/2);
glMultiTexCoord2f(GL_TEXTURE1, 0,Height);
glMultiTexCoord2f(GL_TEXTURE2, Width/2,0);
glMultiTexCoord2f(GL_TEXTURE3, 1,cos(-sign*2*pi/(4.0)));
glMultiTexCoord2f(GL_TEXTURE4, 0,sin(-sign*2*pi/(4.0)));
glVertex2f(0,Height);
glEnd();
//row stages
int t;
TILE_SIZE=BLOCK_SIZE/2;
if(TILE_SIZE > Height) TILE_SIZE=Height;
if(TILE_SIZE > Width) TILE_SIZE=Width;
//these stages are implemented by drawing column aligned quads
for(t=3; t<=(LOGN+2);t++){
int quad_width = (1<< (t-1-2));
if(quad_width==Width) break;
int num_quads = Width/quad_width;
int s=0;
int tex_s=-quad_width;
float angle1= 2*pi/(1<<t);
float angle2 = angle1 *(1<<(t-1));
angle2=-angle2;
angle1=-angle1;
fftstages3_to_rowwidthfp.BindProg();
PingPong2to4();
s=0;
int h=TILE_SIZE;
h = quad_width < TILE_SIZE ? TILE_SIZE : Height;
int num_splits= Height/h;
int ht=0;
int l=quad_width <TILE_SIZE? TILE_SIZE/quad_width:1;
int num_quad_splits = quad_width < TILE_SIZE? Width/TILE_SIZE : num_quads;
glBegin(GL_QUADS);
for(int g=0; g< num_splits;g++){
s=0;
int tex_s=-quad_width;
for(int d=0; d< num_quad_splits;d++)
{
for(int start=0; start<l; start++){
float ang_diff = 2*angle1;
float ang_diff_x = 2*angle1;
if((l==1 && d%2==0) || (l>1 && start%2==0)){//addition
tex_s+=quad_width;
float angle10 = 0-ang_diff;
float angle11 = angle1-ang_diff;
float angle12 = 2*angle1-ang_diff;
float angle13 = 3*angle1-ang_diff;
glMultiTexCoord3f(GL_TEXTURE0, tex_s,ht/2,(ht+Height)/2);
glMultiTexCoord3f(GL_TEXTURE1, tex_s+Width/2,sign*angle10, sign*angle11);
glMultiTexCoord2f(GL_TEXTURE2, sign*angle12,sign*angle13);
glVertex2f( s, ht);
glMultiTexCoord3f(GL_TEXTURE0,tex_s+quad_width,ht/2,(ht+Height)/2);
glMultiTexCoord3f(GL_TEXTURE1,tex_s+quad_width+Width/2,sign*(angle2-4*angle1+ang_diff_x),sign*(angle2-3* angle1+ang_diff_x));
glMultiTexCoord2f(GL_TEXTURE2, sign*(angle2-2*angle1+ang_diff_x),sign*(angle2-angle1+ang_diff_x));
glVertex2f( s+quad_width, ht);
glMultiTexCoord3f(GL_TEXTURE0,tex_s+quad_width,(ht+h)/2,(ht+h+Height)/2);
glMultiTexCoord3f(GL_TEXTURE1,tex_s+quad_width+Width/2, sign*(angle2-4*angle1+ang_diff_x),sign*(angle2-3* angle1+ang_diff_x));
glMultiTexCoord2f(GL_TEXTURE2, sign*(angle2-2*angle1+ang_diff_x),sign*(angle2-angle1+ang_diff_x));
glVertex2f( s+quad_width, ht+h);
glMultiTexCoord3f(GL_TEXTURE0,tex_s,(ht+h)/2,(ht+h+Height)/2);
glMultiTexCoord3f(GL_TEXTURE1,tex_s+Width/2, sign*angle10, sign*angle11);
glMultiTexCoord2f(GL_TEXTURE2, sign*angle12,sign*angle13);
glVertex2f( s, ht+h);
}
s+=quad_width;
}
}
ht+= h;
}
glEnd();
copyfp.BindProg();
PingPong4to2();
glBegin(GL_QUADS);
ht=0;
for(z=0; z< num_splits;z++){
s=0;
for(int d=0; d< num_quad_splits;d++)
{
for(int start=0; start<l; start++){
if((l==1 && d%2==1) || (l>1 && start%2==1)){//addition
glTexCoord2f(s-quad_width, ht);
glVertex2f( s, ht);
glTexCoord2f( s, ht);
glVertex2f( s+quad_width, ht);
glTexCoord2f( s, ht+h);
glVertex2f( s+quad_width, ht+h);
glTexCoord2f( s-quad_width, ht+h);
glVertex2f( s, ht+h);
}
s+=quad_width;
}
}
ht+= h;
}
glEnd();
}
if(usedfor2dfft){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return;
}
TILE_SIZE=BLOCK_SIZE;
if(TILE_SIZE > Width) TILE_SIZE=Width;
if(TILE_SIZE > Height) TILE_SIZE=Height;
//this single stage is the transition from column-aligned quads to row-aligned quads
if(t<=LOGN+2){
fullscreenrowwidthfp.BindProg();
int quad_width=Width;
float angle1= 2*pi/(1<<t);
float angle2 = angle1 *(1<<(t-1));
angle2=-angle2;
angle1=-angle1;
float ang_diff = 2*angle1;
float ang_diff_x = 2*angle1;
PingPong();
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 0,0);
glMultiTexCoord2f(GL_TEXTURE1, 0,Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*(0-ang_diff), sign*(angle1-ang_diff));
glMultiTexCoord2f(GL_TEXTURE4, sign*(2*angle1-ang_diff),sign*(3*angle1-ang_diff));
glVertex2f((float) 0, (float)0);
glMultiTexCoord2f(GL_TEXTURE0,Width,0);
glMultiTexCoord2f(GL_TEXTURE1, Width,Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*(angle2-4*angle1+ang_diff_x),sign*(angle2-3* angle1+ang_diff_x));
glMultiTexCoord2f(GL_TEXTURE4, sign*(angle2-2*angle1+ang_diff_x),sign*(angle2-angle1+ang_diff_x));
glVertex2f((float) Width, (float) 0);
glMultiTexCoord2f(GL_TEXTURE0,Width,Height/2.0);
glMultiTexCoord2f(GL_TEXTURE1, Width,Height);
glMultiTexCoord2f(GL_TEXTURE3, sign*(angle2-4*angle1+ang_diff_x),sign*(angle2-3* angle1+ang_diff_x));
glMultiTexCoord2f(GL_TEXTURE4, sign*(angle2-2*angle1+ang_diff_x),sign*(angle2-angle1+ang_diff_x));
glVertex2f((float) Width, (float) Height);
glMultiTexCoord2f(GL_TEXTURE0,0,Height/2.0);
glMultiTexCoord2f(GL_TEXTURE1,0,Height);
glMultiTexCoord2f(GL_TEXTURE3, sign*(0-ang_diff), sign*(angle1-ang_diff));
glMultiTexCoord2f(GL_TEXTURE4, sign*(2*angle1-ang_diff),sign*(3*angle1-ang_diff));
glVertex2f((float) 0, (float) Height);
glEnd();
t++;
}
//perform the remaining stages using row-aligned quads
for(;t<=(LOGN+2);t++){
int quad_height = (1<<(t-1))/(Width*4);
int num_quads = Height/quad_height;
int s=0;
int tex_s=-quad_height;
fftstages_twicerowwidth_to_n_fp.BindProg();
PingPong2to4();
float angle1= 2*pi/((1<<t));
float angle2 = angle1 *(1<<(t-1));
angle1=-angle1;
angle2=-angle2;
int w=TILE_SIZE;
w = quad_height < TILE_SIZE ? TILE_SIZE : Width;
int num_splits= Width/w;
int wt=0;
int l=quad_height <TILE_SIZE? TILE_SIZE/quad_height:1;
int num_quad_splits = quad_height < TILE_SIZE? Height/TILE_SIZE : num_quads;
glBegin(GL_QUADS);
for(z=0; z< num_splits;z++){
s=0;
int tex_s=-quad_height;
for(int d=0; d< num_quad_splits;d++)
{
for(int start=0; start<l; start++){
float ang_diff_y = 0.5*(4*Width*angle1);//divide by zero issue???
float ang_diff_x = 2*angle1 ;
float offset=0;
if((l==1 && d%2==0) || (l>1 && start%2==0)){//addition
tex_s+=quad_height;
glMultiTexCoord2f(GL_TEXTURE0, wt, tex_s);
glMultiTexCoord2f(GL_TEXTURE1, wt, tex_s+Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*(wt*angle1*4-ang_diff_x- ang_diff_y+offset), sign*(wt*angle1*4+angle1-ang_diff_x- ang_diff_y+offset));
glMultiTexCoord2f(GL_TEXTURE4, sign*(wt*angle1*4+2*angle1-ang_diff_x- ang_diff_y+offset),sign*(wt*angle1*4+3*angle1-ang_diff_x - ang_diff_y+offset));
glVertex2f(wt,s);
glMultiTexCoord2f(GL_TEXTURE0,wt+w, tex_s);
glMultiTexCoord2f(GL_TEXTURE1,wt+w, tex_s+Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*((wt+w)*angle1*4-4*angle1+ang_diff_x-ang_diff_y+offset), sign*((wt+w)*angle1*4-3* angle1+ang_diff_x-ang_diff_y+offset));
glMultiTexCoord2f(GL_TEXTURE4, sign*((wt+w)*angle1*4-2*angle1+ang_diff_x-ang_diff_y+offset), sign*((wt+w)*angle1*4-angle1+ang_diff_x-ang_diff_y+offset));
glVertex2f(wt+w,s);
glMultiTexCoord2f(GL_TEXTURE0, wt+w, tex_s+quad_height);
glMultiTexCoord2f(GL_TEXTURE1, wt+w, tex_s+quad_height+Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*((quad_height-1)*Width*angle1*4 + (wt+w)*angle1*4 -4*angle1+ang_diff_x+ang_diff_y+offset), sign*((quad_height-1)*Width*angle1*4 + (wt+w)*angle1*4- 3*angle1+ang_diff_x+ang_diff_y+offset));
glMultiTexCoord2f(GL_TEXTURE4, sign*((quad_height-1)*Width*angle1*4 + (wt+w)*angle1*4 -2*angle1+ang_diff_x+ang_diff_y+offset), sign*((quad_height-1)*Width*angle1*4 + (wt+w)*angle1*4- angle1+ang_diff_x+ang_diff_y+offset));
glVertex2f(wt+w,s+quad_height);
glMultiTexCoord2f(GL_TEXTURE0,wt, tex_s+quad_height);
glMultiTexCoord2f(GL_TEXTURE1,wt, tex_s+quad_height+Height/2);
glMultiTexCoord2f(GL_TEXTURE3, sign*((quad_height-1)*Width*angle1*4 +wt *4*angle1-ang_diff_x+ ang_diff_y+offset), sign*((quad_height-1)*Width*angle1*4+wt *4*angle1+ angle1-ang_diff_x+ ang_diff_y+offset));
glMultiTexCoord2f(GL_TEXTURE4, sign*((quad_height-1)*Width*angle1*4 +wt *4*angle1+2*angle1-ang_diff_x+ ang_diff_y+offset), sign*((quad_height-1)*Width*angle1*4+wt *4*angle1+3*angle1-ang_diff_x+ang_diff_y+offset));
glVertex2f(wt,s+quad_height);
}
s+=quad_height;
}
}
wt+=w;
}
glEnd();
copyfp.BindProg();
PingPong4to2();
wt=0;
glBegin(GL_QUADS);
for(z=0; z< num_splits;z++){
s=0;
int tex_s=-quad_height;
for(int d=0; d< num_quad_splits;d++)
{
for(int start=0; start<l; start++){
float ang_diff_y = 0.5*(4*Width*angle1);//divide by zero issue???
float ang_diff_x = 2*angle1 ;
float offset=0;
if((l==1 && d%2==1) || (l>1 && start%2==1)){//addition
glTexCoord2f(wt,s-quad_height);
glVertex2f(wt,s);
glTexCoord2f(wt+w,s-quad_height);
glVertex2f(wt+w,s);
glTexCoord2f(wt+w,s);
glVertex2f(wt+w,s+quad_height);
glTexCoord2f(wt,s);
glVertex2f(wt,s+quad_height);
}
s+=quad_height;
}
}
wt+=w;
}
glEnd();
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -