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

📄 sparsematrixvectormultiply2.cpp

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

#include "stdafx.h"
#include "shadow.h"
#include "SparseMatrixOnGPU2.h"
#include "SparseMatrixVectorMultiply2.h"

#include "FragmentProgram.h"
#include "CommonHW.h"
#include "pbuffer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////////
/// From Brook System in 2003
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
///// Multipass to realize the sparse matrix --- vector
///// Just ONE channel
void BrookSparseMatVecFP(const CBrookMatrix& A, const CVectorOnGPU& x, CVectorOnGPU& result)
{
	int i,nPass = A.GetPassNum();
	////////////////////////////////////////////
	///If the size is compatible, then error occurs
	if(A.GetDim() != x.GetVectorLength())
	{
		AfxMessageBox("Error to Operate on Matrix-Vector Multiply for different size!");
		return;
	}

	////////////////////////////////////////////
	///Ax---->Matrix-Vector Product
	unsigned int ShaderID;

	unsigned int _iTextureTarget = x.GetTextureTarget();
	int Width  = x.GetWidth();
	int Height = x.GetHeight(); 

	if(_iTextureTarget == GL_TEXTURE_2D)
	{
		AfxMessageBox("Not support GL_TEXTURE_2D in current system(BrookSparseMatVecFP) for the reason of float precision!");
		return;
	}

	ShaderID = GlobeShaderID[CL_BROOK_SPARSE_MAT_VECT].ShaderID;
	//LoadFragmentProgramFromFile("..\\SDmatvectorRECT.fp", ShaderID);
	//////////////////////////////////////////////
	///// Clear the framebuffer firstly to avoid the previous computation
	///// This step is important to avoid computation errors
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	//glDisable(GL_DEPTH_TEST);


	unsigned char strTexPara[] = "TexPARA";
	int len = strlen((const char*)strTexPara);
	float TexelPara[4];
	TexelPara[0] = 0;
	TexelPara[1] = A.GetDataWidth();
	TexelPara[2] = Width;
	TexelPara[3] = 1.0f/TexelPara[1];
	
	//////////////////////////////////////////////////////////////////////////
	//# Vector X  ----TEX0 
	//# Element   ----TEX1 -- _iDataTexID  // record the non zero elements
	//# Position  ----TEX2 -- _iPosTexID;  // record the accordingly position(Column J)of each non zero element
	//# StartPos  ----TEX3 -- _iStartTexID;// record the first non zero element's position(Column J) of each row
	//# Length    ----TEX4 -- _iLenTexID;  // record the length of each row which sum non zero
	//# Previous  ====TEX5 //////record the previous result
	////##################################################################
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glClear(GL_COLOR_BUFFER_BIT);	
		//////////////////////////////////////////////
		/// Tex0 --x
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(_iTextureTarget, x.GetTextureID());	

		//////////////////////////////////////////////
		/// Tex1 ---A._iDataTexID
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, A.GetDataTextureID());	

		//////////////////////////////////////////////
		/// Tex2 ---A._iPosTexID
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(_iTextureTarget, A.GetPosTextureID());

		//////////////////////////////////////////////
		/// Tex3 ---A._iStartTexID
		glActiveTextureARB(GL_TEXTURE3_ARB);
		glBindTexture(_iTextureTarget, A.GetStartTextureID());

		//////////////////////////////////////////////
		/// Tex4 ---A._iLenTexID
		glActiveTextureARB(GL_TEXTURE4_ARB);
		glBindTexture(_iTextureTarget, A.GetLenTextureID());

		//////////////////////////////////////////////
		/// Tex5 ---previous result
		glActiveTextureARB(GL_TEXTURE5_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		result.SetZero();

		glEnable(GL_FRAGMENT_PROGRAM_NV);
		glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID);
		pbuffer[i]->EndCapture();
	}

	////##################################################################
	int WhichPBuffer;
	for(i=0; i<nPass; i++)
	{	
		WhichPBuffer = i%2;
		glBindTexture(_iTextureTarget, result.GetTextureID());
		pbuffer[WhichPBuffer]->BeginCapture();
		/// Transfer the Pass No. into fragment program
		TexelPara[0] = (float)i;
		glProgramNamedParameter4fvNV(ShaderID,  len, strTexPara, TexelPara);
		
		glBegin( GL_QUADS );
			glVertex2i( 0, 0 );
			glVertex2i( Width, 0 );
			glVertex2i( Width, Height );
			glVertex2i( 0, Height );
		glEnd();

		// Now we need to copy the resulting pixels into the output
		// save the result texture into result
		//glActiveTextureARB(GL_TEXTURE5_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		//glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
		pbuffer[WhichPBuffer]->EndCapture();

	}

/*
	for(i=1;i>=0;i--)
	{
		pbuffer[i]->BeginCapture();
		glDisable(GL_FRAGMENT_PROGRAM_NV);
		pbuffer[i]->EndCapture();
	}
*/
	return;
}

//////////////////////////////////////////////////////////////////////////
/// Modified Brook Method by Youquan Liu
/// Date: 2004/1/6
/// Element & Position -->Tex1
/// StartPos & Length---->TEX2
//////////////////////////////////////////////////////////////////////////
void MultiBrookSparseMatVecFP(const CBrookMatrix& A, const CVectorOnGPU& x, CVectorOnGPU& result)
{
	int i,nPass = A.GetPassNum();
	////////////////////////////////////////////
	///If the size is compatible, then error occurs
	if(A.GetDim() != x.GetVectorLength())
	{
		AfxMessageBox("Error to Operate on Matrix-Vector Multiply for different size!");
		return;
	}

	////////////////////////////////////////////
	///Ax---->Matrix-Vector Product
	unsigned int ShaderID;

	unsigned int _iTextureTarget = x.GetTextureTarget();
	int Width  = x.GetWidth();
	int Height = x.GetHeight(); 

	if(_iTextureTarget == GL_TEXTURE_2D)
	{
		AfxMessageBox("Not support GL_TEXTURE_2D in current system(BrookSparseMatVecFP) for the reason of float precision!");
		return;
	}

	ShaderID = GlobeShaderID[CL_MULTI_BROOK_SPARSE_MAT_VECT].ShaderID;
	//LoadFragmentProgramFromFile("..\\MultiSDmatvectorRECT.fp", ShaderID);

	//////////////////////////////////////////////
	///// Clear the framebuffer firstly to avoid the previous computation
	///// This step is important to avoid computation errors
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	//glDisable(GL_DEPTH_TEST);

	unsigned char strTexPara[] = "TexPARA";
	int len = strlen((const char*)strTexPara);
	float TexelPara[4];
	TexelPara[0] = 0;
	TexelPara[1] = A.GetDataWidth();
	TexelPara[2] = Width;
	TexelPara[3] = 1.0f/TexelPara[1];
	
	//////////////////////////////////////////////////////////////////////////
	//# Vector X  ----TEX0 
	//# Element & Position---TEX1 -- _iDataTexID  // record the non zero elements
	//#                           -- _iPosTexID;  // record the accordingly position(Column J)of each non zero element
	//# StartPos & Length----TEX2 -- _iStartTexID; // record the first non zero element's position(Column J) of each row
	//#                           -- _iLenTexID;   // record the length of each row which sum non zero
	//# Previous  ====TEX5 //////record the previous result
	////##################################################################
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glClear(GL_COLOR_BUFFER_BIT);	
		//////////////////////////////////////////////
		/// Tex0 --x
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(_iTextureTarget, x.GetTextureID());	

		//////////////////////////////////////////////
		/// Tex2 ---A._iDataTexID&A._iPosTexID
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(_iTextureTarget, A.GetDataTextureID());	

		//////////////////////////////////////////////
		/// Tex3 ---A._iStartTexID&A._iLenTexID
		glActiveTextureARB(GL_TEXTURE3_ARB);
		glBindTexture(_iTextureTarget, A.GetStartTextureID());

		//////////////////////////////////////////////
		/// Tex1 ---previous result
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		result.SetZero();		

		glEnable(GL_FRAGMENT_PROGRAM_NV);
		glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID);
		pbuffer[i]->EndCapture();
	}

	////##################################################################
	int WhichPBuffer;
	for(i=0; i<nPass; i++)
	{	
		WhichPBuffer = i%2;
		glBindTexture(_iTextureTarget, result.GetTextureID());
		pbuffer[WhichPBuffer]->BeginCapture();
		/// Transfer the Pass No. into fragment program
		TexelPara[0] = (float)i;
		glProgramNamedParameter4fvNV(ShaderID,  len, strTexPara, TexelPara);
		
		glBegin( GL_QUADS );
			glVertex2i( 0, 0 );
			glVertex2i( Width, 0 );
			glVertex2i( Width, Height );
			glVertex2i( 0, Height );
		glEnd();

		// Now we need to copy the resulting pixels into the output
		// save the result texture into result
		glBindTexture(_iTextureTarget, result.GetTextureID());
		//glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
		pbuffer[WhichPBuffer]->EndCapture();
	}
	
/*
	for(i=1;i>=0;i--)
	{
		pbuffer[i]->BeginCapture();
		glDisable(GL_FRAGMENT_PROGRAM_NV);
		pbuffer[i]->EndCapture();
	}
*/
	return;
}


⌨️ 快捷键说明

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