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

📄 vectorongpu.cpp

📁 PDE simulator on GPU.
💻 CPP
字号:
// VectorOnGPU.cpp: implementation of the VectorOnGPU class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "shadow.h"
#include "VectorOnGPU.h"

#include "CommonHW.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

///////////////////////////////////////////////////////////////////////////////////////
/// General-Purpose Computation with GPU
/// Author: Youquan Liu
/// Website: http://lcs.ios.ac.cn/~lyq/
/// Date:   2003/8/21
/// Modified Date: 2003/12/2
/// Location: Labatory of Computer Science, Institute of Software, 
///            Chinese Academy of Sciences, P.R.China
/// Class: CVectorOnGPU
///////////////////////////////////////////////////////////////////////////////////////
CVectorOnGPU::CVectorOnGPU()
{
	_iTexID = 0;
	_bInitialized = false;
	_bFloat = g_Float;
	_iChannelsNum = g_ChannelsNum;
}

CVectorOnGPU::~CVectorOnGPU()
{
	glDeleteTextures(1,&_iTexID);
}

//////////////////////////////////////////////////////////////////////////////////////////////
///////NOTE: here can be optimized to incorpate the adjacent 4 elements into ONE texel by RGBA
///////      But, now,just simple method is used.
///////      After this, we must optimize it.
/////// ONE Channel & Four Channels Together
//////////////////////////////////////////////////////////////////////////////////////////////
void CVectorOnGPU::SetData(const float *M, const int DimSize)
{
	////Vector's Length
	_iLength = DimSize;

	GLuint iInternalFormat;
	GLuint iFormat;

	float *fInputVector = NULL;
	if( _iChannelsNum == 1)
	{
		//// Determine the format of texture according to specifications
		if(_bFloat == true )
		{
			iInternalFormat = GL_FLOAT_R32_NV;
			iFormat = GL_RED;
		}
		else
		{
			iInternalFormat = GL_LUMINANCE;
			iFormat = GL_RED;
		}
		
		//// Previous Method: Texture resolution = res*res (NOTE: square)
		//// Last Modified Date: 2003/10/23
		//// ------To get appropriate Texture Size to reduce reduction
		CalOptTexRSize(_iLength, _iHeight, _iWidth);

		fInputVector = new float[_iHeight * _iWidth];
		if( fInputVector == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::SetData!");
			return;
		}

		////Initialize it to zero
		memset(fInputVector, 0, sizeof(float) * _iHeight * _iWidth);

		if(M != NULL)
		{
			////Fill it with the input vector M
			memcpy(fInputVector, M, sizeof(float) * _iLength);
		}
	}
	else//// 4 Channels
	{
		//// Determine the format of texture according to specifications
		if(_bFloat == true )
		{
			iInternalFormat = GL_FLOAT_RGBA32_NV;
			iFormat = GL_RGBA;
		}
		else
		{
			iInternalFormat = GL_RGBA8;
			iFormat = GL_RGBA;
		}
		
		CalOptTexRGBASize(_iLength, _iHeight, _iWidth);

		fInputVector = new float[_iHeight * _iWidth * 4];
		if( fInputVector == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::SetData!");
			return;
		}

		////Initialize it to zero
		memset(fInputVector, 0, sizeof(float) * _iHeight * _iWidth * 4);

		if(M != NULL)
		{
			////Fill it with the input vector M
			memcpy(fInputVector, M, sizeof(float) * _iLength);
		}
	}

	_iTextureTarget = g_TextureTarget;

	////Generate DimSize Textures
	glGenTextures(1,&_iTexID);
	glBindTexture(_iTextureTarget,_iTexID);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexParameterf(_iTextureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameterf(_iTextureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);	

	glTexParameterf(_iTextureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameterf(_iTextureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	
	glTexImage2D(_iTextureTarget, 0, iInternalFormat, _iWidth, _iHeight, 0, iFormat, GL_FLOAT, fInputVector );

	delete[] fInputVector;
	fInputVector = NULL;

	_bInitialized = true;
	return;
}

//////////////////////////////////////////////////////////////////////////////////////////////
///////NOTE: Set the texture data to zero
/////// ONE Channel
//////////////////////////////////////////////////////////////////////////////////////////////
void CVectorOnGPU::SetZero()
{
	GLuint iInternalFormat;
	GLuint iFormat;

	///// Because just set to zero, DONOT consider float or not.
	float *Zero = NULL;
	if( _iChannelsNum == 1)
	{
		//// Determine the format of texture according to specifications
		if(_bFloat == true )
		{
			iInternalFormat = GL_FLOAT_R32_NV;
			iFormat = GL_RED;
		}
		else
		{
			iInternalFormat = GL_LUMINANCE;
			iFormat = GL_RED;
		}
		
		Zero = new float[_iHeight * _iWidth];
		if(Zero == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::SetZero!");
			return ;
		}		
		memset(Zero, 0, sizeof(float) * _iHeight * _iWidth);
	}
	else
	{
		//// Determine the format of texture according to specifications
		if(_bFloat == true )
		{
			iInternalFormat = GL_FLOAT_RGBA32_NV;
			iFormat = GL_RGBA;
		}
		else
		{
			iInternalFormat = GL_RGBA8;
			iFormat = GL_RGBA;
		}
		
		Zero = new float[_iHeight * _iWidth * 4];
		if(Zero == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::SetZero!");
			return ;
		}
		memset(Zero, 0, sizeof(float) * _iHeight * _iWidth * 4);
	}	

	glBindTexture(_iTextureTarget, _iTexID);
	glTexImage2D(_iTextureTarget, 0, iInternalFormat, _iWidth, _iHeight, 0, iFormat, GL_FLOAT, Zero );

	delete[] Zero;
	Zero = NULL;

	_bInitialized = true;
	return;
}


///////////////////////////////////////////////////////////////////////////////////////
//// Retrieve the data from the texture
//// ONE Channel & Four Channels
//// NOTE: all values are clamped to [0,1] if not FLOAT supported
////////////////////////////////////////////////////////////////////////////////////////////
float* CVectorOnGPU::GetData(int &DimSize)
{
	DimSize = _iLength;
	float *fOutputVector = NULL;
	fOutputVector = new float[DimSize];
	if(fOutputVector == NULL)
	{
		AfxMessageBox("Error to allocate memory in CVectorOnGPU::GetData!");
		return NULL;
	}
	memset(fOutputVector, 0, sizeof(float)*DimSize);

	GLuint iFormat;

	float *fOutputTex = NULL;
	if( _iChannelsNum == 1)
	{
		fOutputTex = new float[_iHeight * _iWidth];
		if(fOutputTex == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::GetData!");
			return NULL;
		}		
		memset(fOutputTex, 0, sizeof(float) * _iHeight * _iWidth);
		iFormat = GL_RED;
	}
	else/// 4 Channels
	{
		fOutputTex = new float[_iHeight * _iWidth * 4];
		if(fOutputTex == NULL)
		{
			AfxMessageBox("Error to allocate memory in CVectorOnGPU::GetData!");
			return NULL;
		}
		memset(fOutputTex, 0, sizeof(float) * _iHeight * _iWidth * 4);
		iFormat = GL_RGBA;
	}

	glBindTexture(_iTextureTarget, _iTexID);
	glGetTexImage(_iTextureTarget, 0, iFormat, GL_FLOAT, fOutputTex);

	memcpy(fOutputVector, fOutputTex, sizeof(float)*DimSize);
	delete[] fOutputTex;
	fOutputTex = NULL;

	return fOutputVector;
}

//////////////////////////////////////////////////////////////////////////
void CVectorOnGPU::CopyData(CVectorOnGPU inputVector)
{
	_iChannelsNum = inputVector.GetChannelsNum();

	float *fOutputVector = NULL;
	fOutputVector = inputVector.GetData(_iLength);

	GLuint iFormat;
	if( _iChannelsNum == 1)
	{
		iFormat = GL_RED;
	}
	else/// 4 Channels
	{
		iFormat = GL_RGBA;
	}	
	
	glBindTexture(_iTextureTarget, _iTexID);
	glGetTexImage(_iTextureTarget, 0, iFormat, GL_FLOAT, fOutputVector);
	delete[] fOutputVector;
	fOutputVector = NULL;	
}

⌨️ 快捷键说明

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