⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ui.cpp

📁 选自<gpu gemes 2>,用gpu实现快速傅立叶变换
💻 CPP
字号:
/***************************************************************************
*		FILE NAME:  FFTDemo.cpp
*
* ONE LINE SUMMARY:
*		Demostrates 2DFFT in a GPU.
*        
*		Thilaka Sumanaweera
*		Siemens Medical Solutions USA, Inc.
*		1230 Shorebird Way
*		Mountain View, CA 94039
*		USA
*		Thilaka.Sumanaweera@siemens.com
*
* DESCRIPTION:
*
*****************************************************************************
* REVISION HISTORY:
* Rev     When      Who         What
* V1      15Dec2004 Thilaka     Created.
****************************************************************************/
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <FFT.h>

using namespace std;

int WinWidth  = 0;
int WinHeight = 0;
int Width     = 0;
int Height    = 0;

char DisplayOriginal_p = 0;
char Debug_p = 0;

float *imageR = 0;
float *imageI = 0;

FFT *Fft;

// Uncomment the lines below to load different data sizes.
// Each file contains a sync function
//
//char *InputFile = "../bin/Data/SyncFunction_8x8.dat";
//char *InputFile = "../bin/Data/SyncFunction_16x16.dat";
//char *InputFile = "../bin/Data/SyncFunction_16x32.dat";
//char *InputFile = "../bin/Data/SyncFunction_32x32.dat";
//char *InputFile = "../bin/Data/SyncFunction_64x64.dat";
//char *InputFile = "../bin/Data/SyncFunction_128x128.dat";
//char *InputFile = "../bin/Data/SyncFunction_256x256.dat";
//char *InputFile = "../bin/Data/SyncFunction_512x512.dat";
char *InputFile = "../bin/Data/SyncFunction_2048x64.dat";
//char *InputFile = "../bin/Data/SyncFunction_2048x128.dat";


// File format:
//
// Width: an integer containing the value
// Height: an integer containing the value
// A stream of 8 bit data with the fastest moving index along width
void ReadData(char *file)
{
	unsigned char *image;

	ifstream ifile;
	ifile.open(file, ios::out | ios_base::binary);
	if (ifile == NULL) {
		cerr << "Could not open the file: " << file << endl;
		cerr << "Exiting." << endl;
		exit(0);
	}
	ifile.read((char *)&Width, sizeof(int));
	ifile.read((char *)&Height, sizeof(int));
	image = new unsigned char [Width*Height];
	ifile.read((char *)image, Width*Height);
	ifile.close();

	// Allocate real and imaginary buffers
	float *R   = imageR = new float [Width*Height];
	float *I   = imageI = new float [Width*Height];
	
	// Fill the real and imaginary buffers with data
	int s, t;
	float val;
	unsigned char *ptr = image;
	for (t = 0; t < Height; t++) {
		for (s = 0; s < Width; s++) {
			val = *ptr;
			*(R++) = val;
			*(I++) = 0;
			ptr++;
		}
	}
	delete [] image;
}

static void Reshape(int w, int h)
{
	WinWidth  = glutGet(GLUT_WINDOW_WIDTH);
	WinHeight = glutGet(GLUT_WINDOW_HEIGHT);

	glViewport(0, 0, (GLsizei) w, (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, Fft->Width, 0.0, Fft->Height, -1, +1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

static void Display(void)
{
	if (DisplayOriginal_p) {
		Fft->DisplayInputImage(WinWidth, WinHeight);
	}
	else {
		Fft->DoFFT();
		Fft->DisplayOutputImage(WinWidth, WinHeight);
	}
	glutSwapBuffers();
}

static void Idle(void)
{
	static clock_t thisClock, startClock = clock();
	static int numTimes     = 0;
	int avgCount            = 100;
	float FrameRate         = 0.0;
	static bool FirstTime_p = true;

	if (FirstTime_p) {
		// Draw a blue quad to look at.
		Reshape(WinWidth, WinHeight);
		glColor3f(0.0, 0.0, 1.0);
		glBegin(GL_QUADS);
		glVertex2f(0.0, 0.0);
		glVertex2f(Width, 0.0);
		glVertex2f(Width, Height);
		glVertex2f(0.0, Height);
		glEnd();
		glColor3f(1.0, 1.0, 1.0);
		Fft->Print(10, 15, "Optimizing xCutOff and yCutOff. Wait...", GLUT_BITMAP_HELVETICA_12);
		glutSwapBuffers();
		Fft->FindOptimalTransitionPoints();
		FirstTime_p = false;
	}

	if (numTimes == avgCount) {
		thisClock = clock();
		FrameRate = Fft->ComputeFrameRate(avgCount, thisClock, startClock);
		startClock = thisClock;
		numTimes = 0;
		cerr << "Frame Rate = " << FrameRate << endl;
	}

	Display();
	numTimes++;
}

void PrintHelp(void)
{
	cerr << endl;
	cerr << "Demonstrates 2D FFT using the GPU" << endl;
	cerr << "      Thilaka Sumanaweera, 12/15/2004" << endl;
	cerr << "      Siemens Medical Solutions USA, Inc." << endl;
	cerr << "      Mountain View, CA, USA" << endl;
	cerr << endl;
	cerr << " ESC:   quit" << endl;
	cerr << "   1:   toggles showing 1st image or the 2nd image" << endl;
	cerr << "   x:   do FFT in x" << endl;
	cerr << "   y:   do FFT in y" << endl;
	cerr << "   z:   do FFT in x and y" << endl;
	cerr << "   d:   debug mode. Run only one butterfly stage." << endl;
	cerr << "   f:   toggle displaying output or input data" << endl;
	cerr << "   h:   Print this help." << endl;
	cerr << endl;
}

static void Keyboard(unsigned char key, int x, int y)
{
	switch (key) {
	case '1':
		Fft->ShowFirstImage_p = !Fft->ShowFirstImage_p;
		Fft->SetDisplayMask();
		if (Fft->ShowFirstImage_p) {
			cerr << "Show first image." << endl;
		}
		else {
			cerr << "Show second image." << endl;
		}
		break;
	case 'f':
		DisplayOriginal_p = !DisplayOriginal_p;
		if (DisplayOriginal_p) {
			cerr << "Showing input." << endl;
		}
		else {
			cerr << "Showing output." << endl;
		}
		break;
	case 'x':
		Fft->type = X;
		cerr << "1DFFT in x" << endl;
		break;
	case 'y':
		Fft->type = Y;
		cerr << "1DFFT in y" << endl;
		break;
	case 'z':
		Fft->type = XY;
		cerr << "2DFFT" << endl;
		break;
	case 'd':
		Debug_p = !Debug_p;
		if (Debug_p) {	
			Fft->nButterfliesXWorking = 1;
			Fft->nButterfliesYWorking = 1;
			cerr << "Debug" << endl;
		}
		else {
			Fft->nButterfliesXWorking = Fft->nButterfliesX;	
			Fft->nButterfliesYWorking = Fft->nButterfliesY;
			cerr << "Not debug" << endl;
		}
		break;
	case 'h':
		PrintHelp();
		break;
	case 27:
		delete [] imageR;
		delete [] imageI;
		delete Fft;
		exit(0);
		break;
	default:
		break;
	}
}

static void InitializeGlut(int *argc, char *argv[])
{
	glutInit(argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(WinWidth, WinHeight);
    glutInitWindowPosition(0, 0);
	glutCreateWindow(argv[0]);

	GLenum err = glewInit();
	if (GLEW_OK != err) {
		cerr << "Could not initialize GLEW!" << endl;
		exit(0);
	}
	// Turn off wait for vertical sync
	wglSwapIntervalEXT(0);
	glutDisplayFunc(Display);
    glutReshapeFunc(Reshape);
	glutIdleFunc(Idle);
	glutKeyboardFunc(Keyboard);
}

int main(int argc, char *argv[])
{	
	ReadData(InputFile);

	InitializeGlut(&argc, argv);

	bool ForwardFFT_p = true;					// Set to false to get reverse FFT
	PingMethod PMethod = AUTO_PBUFFER;			// Use to select the single/double buffer method for your hardware
	// PingMethod PMethod = SINGLE_PBUFFER;		// Select the single buffer method (NVIDIA Quadro board is needed)
	// PingMethod PMethod = DOUBLE_PBUFFER;		// Select the double buffer method

	Fft = new FFT(ForwardFFT_p, PMethod, Width, Height);
	Fft->UploadData(imageR, imageI, imageR, imageI);
	Fft->ComputeMaxAndEnergy(imageR, imageI, imageR, imageI);

	// Resize the display window
	int sh = glutGet(GLUT_SCREEN_HEIGHT)-300;
	int sw = glutGet(GLUT_SCREEN_WIDTH)-300;
	float aspect = (float)(Fft->Height)/(float)(Fft->Width);
	if (aspect > 1.0) {
		WinHeight = sh;
		WinWidth  = (float)WinHeight/aspect;
	}
	else {
		WinWidth = sw;
		WinHeight = (float)WinWidth*aspect;
	}
	WinWidth *= 0.5;
	WinHeight *= 0.5;
	glutReshapeWindow(WinWidth, WinHeight);
	glutPositionWindow(sw-WinWidth, sh-WinHeight); 

	cerr << "Input array: [" << Fft->Width << " x " << Fft->Height << "]" << endl;
	cerr << "Performance is independent of displayed image size," << endl;
	cerr << "which is shrunk to fit the screen." << endl;

	PrintHelp();
	glutMainLoop();

	Fft->DestroyCgPrograms();
	
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -