📄 densematrixongpu.cpp
字号:
/////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 + -