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

📄 densematrixongpu.cpp

📁 PDE simulator on GPU.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			/////Fill the output matrix  with textures which arranged in diagonal
			///// _iDim <= Height*Width
			for(i=0; i<_iDim; i++)
			{
				////////retore the matrix data from diagonal textures
				k = i*_iDim + (i+l)%_iDim;
				fOutputMatrix[k] = fOutputTex[i];
			}		
		}		
	}
	else
	{
		fOutputTex = new float[_iHeight * _iWidth * 4];
		if(fOutputTex == NULL)
		{
			AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetData!");
			return NULL;
		}
		
		memset(fOutputTex, 0, sizeof(float) * _iHeight * _iWidth * 4);
		for(l=0; l<MaxTexNum; l++)
		{
			glBindTexture(_iTextureTarget, _iTexID[l]);
			glGetTexImage(_iTextureTarget, 0, GL_RGBA, GL_FLOAT, fOutputTex);
			/////Here re-arrange so many textures into A Correct Matrix
			/////Fill the output matrix  with textures which arranged in diagonal
			///// _iDim <= Height*Width
			for(i=0; i<_iDim; i++)
			{
				////////retore the matrix data from diagonal textures
				k = i*_iDim + (i+l)%_iDim;
				fOutputMatrix[k] = fOutputTex[i];
			}		
		}	
	}


	delete[] fOutputTex;
	fOutputTex = NULL;

	return fOutputMatrix;
}

///////////////////////////////////////////////////////////////////////////////////////
/// Retrieve the data from the texture for matrix * matrix
/// NOTE: all values are clamped to [0,1]  if not FLOAT supported
///       Texture[m][n]
////////////////////////////////////////////////////////////////////////////////////////////
float* CDenseMatrixOnGPU::GetData(int &m, int &n)
{
	float *fOutputMatrix = NULL;
	if(_iChannelsNum == 1)
	{
		m = _iHeight;
		n = _iWidth;
		fOutputMatrix = new float[m*n];
		if(fOutputMatrix == NULL)
		{
			AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetData!");
			return NULL;
		}
		
		memset(fOutputMatrix, 0, sizeof(float) * _iHeight * _iWidth);

		/////Just ONE channel
		glBindTexture(_iTextureTarget, _iWholeTexID);
		glGetTexImage(_iTextureTarget, 0, GL_RED, GL_FLOAT, fOutputMatrix);
	}
	else/////4 channels
	{
		int i,j;
		//// If FOUR channels
		m = _iHeight*2;
		n = _iWidth*2;	
		
		fOutputMatrix = new float[m*n];
		if(fOutputMatrix == NULL)
		{
			AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetData!");
			return NULL;
		}	
		memset(fOutputMatrix, 0, sizeof(float) * m * n);

		///// Texture is half size of Matrix
		float *fOutputTex = NULL;
		fOutputTex = new float[_iHeight*_iWidth*4];
		if(fOutputTex == NULL)
		{
			AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetData!");
			return NULL;
		}	
		memset(fOutputTex, 0, sizeof(float) * _iHeight * _iWidth * 4);

		glBindTexture(_iTextureTarget, _iWholeTexID);
		glGetTexImage(_iTextureTarget, 0, GL_RGBA, GL_FLOAT, fOutputTex);

		//// Re-arrange the RGBA texture data into a Single Matrix--->fOutputMatrix
		for(i=0; i<_iHeight; i++)
		{
			for(j=0; j<_iWidth; j++)
			{
				//// R
				fOutputMatrix[i*n + j]                      = fOutputTex[(i*_iWidth + j)*4];
				//// G
				fOutputMatrix[i*n + j + _iWidth]            = fOutputTex[(i*_iWidth + j)*4+1];
				//// B
				fOutputMatrix[(i+_iHeight)*n + j]           = fOutputTex[(i*_iWidth + j)*4+2];
				//// A
				fOutputMatrix[(i+_iHeight)*n + j + _iWidth] = fOutputTex[(i*_iWidth + j)*4+3];
			}
		}
		delete[] fOutputTex;
		fOutputTex = NULL;
	}

	return fOutputMatrix;
}

//////////////////////////////////////////////////////////////////////////
/// New Method developed by Youquan Liu 2004/1/5
/// Re-arrange the diagonal data into ONE texture RGBA
/// Each diagonal data occupy ONE channel 
/// RECT texture target
//////////////////////////////////////////////////////////////////////////
void CDenseMatrixOnGPU::SetMultiData(float *M, int DimSize)
{
	int i,j,k;
	//// M has N*N elements, here Total Elements Number = _iDim*_iDim
	_iDim = DimSize;

	GLuint iInternalFormat;
	GLuint iFormat;

	////Organize all elements into _iDim diagonal entries.
	////And then generate _iDim Textures(_iHeight*_iWidth)
	////----->fInputMatrix[_iDim][_iHeight*_iWidth]
	float **fInputMatrix = NULL;
	if( _iChannelsNum != 1)///// 4 Channels
	{
		AfxMessageBox("NOT support in Multi-diagonal data into ONE texture RGBA CDenseMatrixOnGPU::SetMultiData!");
		exit(0);
	}
	
	//// 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;
	}

	//// Previous Method: Texture resolution = res*res (NOTE: square)
	//// Last Modified Date: 2003/10/23
	//// ------To get appropriate Texture Size to reduce reduction
	//// Texture size = Height*Width
	CalOptTexRSize(_iDim, _iHeight, _iWidth);
/*
	if(IsPowerOfTwo(_iWidth) && IsPowerOfTwo(_iHeight) && _bFloat == false)
	{
		_iTextureTarget = GL_TEXTURE_2D;
	}
	else
		_iTextureTarget = GL_TEXTURE_RECTANGLE_NV;
*/
	_iTextureTarget = g_TextureTarget;

	//////////////////////////////////////////////////////////////////////////
	////BUT here we must calculate the TexID number carefully to maximize the
	////current hardware resource.
	////FLUSH all channels RGBA
	MaxTexNum = (int)ceil((float)_iDim/4.0);
	LeftNum = _iDim%4;
	fInputMatrix = new float*[MaxTexNum];
	for(i=0; i<MaxTexNum; i++)
	{
		fInputMatrix[i] = new float[_iHeight * _iWidth * 4];
		memset(fInputMatrix[i], 0, sizeof(float)* _iHeight * _iWidth * 4);
	}
	if(fInputMatrix == NULL)
	{
		AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::SetData!");
		return ;
	}

	if(M != NULL)
	{
		/////Fill the textures with accordingly matrix elements which arranged in diagonal
		for(i=0; i<MaxTexNum-1; i++)
		{
			for(j=0; j<_iDim; j++)
			{
				////////Transfer the Matrix into a set of Diagonal vectors
				k = j*_iDim + (i*4+j)%_iDim;
				fInputMatrix[i][j*4]   = M[k];   //R

				k = j*_iDim + (i*4+1+j)%_iDim;
				fInputMatrix[i][j*4+1] = M[k];   //G

				k = j*_iDim + (i*4+2+j)%_iDim;
				fInputMatrix[i][j*4+2] = M[k];   //B

				k = j*_iDim + (i*4+3+j)%_iDim;
				fInputMatrix[i][j*4+3] = M[k];   //A
			}
		}
		//////////////////////////////////////////////////////////////////////////
		/// Process the left diagonal data according to the current situation
		if(LeftNum == 1)
		{
			for(j=0; j<_iDim; j++)
			{
				////////Transfer the Matrix into a set of Diagonal vectors
				k = j*_iDim + (i*4+j)%_iDim;
				fInputMatrix[i][j*4]   = M[k];

				fInputMatrix[i][j*4+1] = 0.0;

				fInputMatrix[i][j*4+2] = 0.0;

				fInputMatrix[i][j*4+3] = 0.0;
			}
		}
		else if(LeftNum == 2)
		{
			for(j=0; j<_iDim; j++)
			{
				////////Transfer the Matrix into a set of Diagonal vectors
				k = j*_iDim + (i*4+j)%_iDim;
				fInputMatrix[i][j*4]   = M[k];

				k = j*_iDim + (i*4+1+j)%_iDim;
				fInputMatrix[i][j*4+1] = M[k];

				fInputMatrix[i][j*4+2] = 0.0;
				fInputMatrix[i][j*4+3] = 0.0;
			}
		}
		else if(LeftNum == 3)
		{
			for(j=0; j<_iDim; j++)
			{
				////////Transfer the Matrix into a set of Diagonal vectors
				k = j*_iDim + (i*4+j)%_iDim;
				fInputMatrix[i][j*4]   = M[k];

				k = j*_iDim + (i*4+1+j)%_iDim;
				fInputMatrix[i][j*4+1] = M[k];

				k = j*_iDim + (i*4+2+j)%_iDim;
				fInputMatrix[i][j*4+2] = M[k];

				fInputMatrix[i][j*4+3] = 0.0;
			}
		}
		else////Just totally FULL occpied
		{
			for(j=0; j<_iDim; j++)
			{
				////////Transfer the Matrix into a set of Diagonal vectors
				k = j*_iDim + (i*4+j)%_iDim;
				fInputMatrix[i][j*4]   = M[k];

				k = j*_iDim + (i*4+1+j)%_iDim;
				fInputMatrix[i][j*4+1] = M[k];

				k = j*_iDim + (i*4+2+j)%_iDim;
				fInputMatrix[i][j*4+2] = M[k];

				k = j*_iDim + (i*4+3+j)%_iDim;
				fInputMatrix[i][j*4+3] = M[k];
			}
		}
	}


	//////////////////////////////////////////////////////////////////////////
	////Generate  Textures IDs
	if(_iTexID != NULL)
	{
		delete[] _iTexID;
		_iTexID = NULL;
	}
	_iTexID = new unsigned int[MaxTexNum];
	if(_iTexID == NULL)
	{
		AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::SetData!");
		return;
	}
	glGenTextures(MaxTexNum, _iTexID);

	for(i=0; i<MaxTexNum; i++)
	{
		glBindTexture(_iTextureTarget, _iTexID[i]);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		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, fInputMatrix[i] );
	}

	for(i=0; i<MaxTexNum; i++)
	{
		delete[] fInputMatrix[i];
		fInputMatrix[i] = NULL;
	}
	delete[] fInputMatrix;
	fInputMatrix = NULL;

	_bInitialized = true;
}

float* CDenseMatrixOnGPU::GetMultiData(int &DimSize)
{
	int i,k,j;
	int Dim2 = _iDim*_iDim;
	DimSize = _iDim;
	float *fOutputMatrix = NULL;
	fOutputMatrix = new float[Dim2];
	if(fOutputMatrix == NULL)
	{
		AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetMultiData!");
		return NULL;
	}
	memset(fOutputMatrix, 0, sizeof(float) * Dim2);
	float *fOutputTex = NULL;
	if( _iChannelsNum == 1)
	{
		fOutputTex = new float[_iHeight * _iWidth * 4];
		if(fOutputTex == NULL)
		{
			AfxMessageBox("Error to allocate memory in CDenseMatrixOnGPU::GetMultiData!");
			return NULL;
		}
		
		memset(fOutputTex, 0, sizeof(float) * _iHeight * _iWidth * 4);
		for(i=0; i<MaxTexNum; i++)
		{
			glBindTexture(_iTextureTarget, _iTexID[i]);
			glGetTexImage(_iTextureTarget, 0, GL_RGBA, GL_FLOAT, fOutputTex);

			/////Here re-arrange so many textures into A Correct Matrix
			/////Fill the output matrix  with textures which arranged in diagonal
			///// _iDim <= Height*Width
			/////NOTE: fOutputTex[i][j]
			for(j=0; j<_iDim; j++)
			{
				////////retore the matrix data from diagonal textures
				k = j*_iDim + (i*4+j)%_iDim;
				fOutputMatrix[k] = fOutputTex[j*4];
				
				k = j*_iDim + (i*4+1+j)%_iDim;
				if(k<Dim2)
					fOutputMatrix[k] = fOutputTex[j*4+1];
		
				k = j*_iDim + (i*4+2+j)%_iDim;
				if(k<Dim2)
					fOutputMatrix[k] = fOutputTex[j*4+2];
				
				k = j*_iDim + (i*4+3+j)%_iDim;
				if(k<Dim2)
					fOutputMatrix[k] = fOutputTex[j*4+3];
			}		

		}		
	}
	else
	{
		AfxMessageBox("NOT supported in CDenseMatrixOnGPU::GetMultiData!");
		return NULL;
	}

	delete[] fOutputTex;
	fOutputTex = NULL;

	return fOutputMatrix;
}

⌨️ 快捷键说明

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