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

📄 densematrixmatrixoperation.cpp

📁 PDE simulator on GPU.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	int nPass  = A.GetWidth();
	if(nPass != B.GetHeight())
	{
		AfxMessageBox("For the reason of unmatched matrix size, it's wrong to muliply two matrices!");
		return;
	}
	if(_iTextureTarget == GL_TEXTURE_2D)
	{
		AfxMessageBox("Not support GL_TEXTURE_2D in current system(clMatMatFP) for the reason of float precision!");
		return;
	}
	
	//// Here Generate the Fragment Program according to the actual matrix size
	char strStart[]= "!!FP1.0\n\
DECLARE OneTexOffset ={0, 0, 0, 0};\n\
MOV R1.y, f[TEX0];\n\
MOV R2.x, f[TEX1];\n\
MOV R1.x, OneTexOffset.w;\n\
MOV R2.y, OneTexOffset.w;\n\
TEX R4, R1, TEX0, RECT;\n\
TEX R5, R2, TEX1, RECT;\n\
MAD R3, R4.xxzz, R5.xyxy, R3;\n\
MAD R3, R4.yyww, R5.zwzw, R3;\n";

	char strStepPart[]=	"ADD R1.x, R1, OneTexOffset.x;\n\
ADD R2.y, R2, OneTexOffset.y;\n\
TEX R4, R1, TEX0, RECT;\n\
TEX R5, R2, TEX1, RECT;\n\
MAD R3, R4.xxzz, R5.xyxy, R3;\n\
MAD R3, R4.yyww, R5.zwzw, R3;\n";

	char strEndPart[]="TEX R4, f[TEX2], TEX2, RECT;\nADD o[COLR], R4, R3;\nEND\0";

	//////////////////////////////////////////////////////////////////////////////////
	///// Multi-Pass Process
	///// Here we change the process into A.GetWidth()/BlockNum passes
	///// In this way, we can compute bigger Matrix within limited instructions number
	int BlockNum = 2;
	
	//// Combine the whole Fragment Program together
	int nSteps = BlockNum - 1;
	int nInstructions = nSteps*6 + 10;
	if(nInstructions > ResourceLimitOnCurrentHW.FragmentProgram.MaxInstructionsNum)
	{
		AfxMessageBox("Due to the instruction limitation, \
			this program can not do such big matrix-matrix multiplication!");
		return;
	}
	int totalsize = strlen(strStart) + 
			        strlen(strEndPart) + 
				    strlen(strStepPart)*nSteps;

	char *strShader = new char[totalsize*2];
	if( strShader == NULL)
	{
		AfxMessageBox("Error to allocate memory for shader string in clMatMat4ChannelFP!");
		return;
	}

	strcpy(strShader, strStart);
	for(i=0;i<nSteps;i++)
	{
		strcat(strShader, strStepPart);
	}
	strcat(strShader, strEndPart);
	LoadFragmentProgramFromString((const unsigned char*)strShader, ShaderID);
	delete[] strShader;

	unsigned char strTexOffset[] = "OneTexOffset";
	int len = strlen((const char*)strTexOffset);

	float TexOffset[] = { 0.0, 0.0, 0.0, 0.0};
	TexOffset[0] = 1.0;///(float)nPass;
	TexOffset[1] = 1.0;///(float)nPass;

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_FRAGMENT_PROGRAM_NV);

	glActiveTextureARB( GL_TEXTURE0_ARB );
	glBindTexture(_iTextureTarget, A.GetWholeTextureID());

	glActiveTextureARB( GL_TEXTURE1_ARB );
	glBindTexture(_iTextureTarget, B.GetWholeTextureID());

	glActiveTextureARB( GL_TEXTURE2_ARB );
	glBindTexture(_iTextureTarget, result.GetWholeTextureID());
	
	for(i=0; i<nPass; i+=BlockNum)
	{
		glActiveTextureARB( GL_TEXTURE2_ARB );
		glBindTexture(_iTextureTarget, result.GetWholeTextureID());

		TexOffset[3] = (float)i;
		glProgramNamedParameter4fvNV(ShaderID,  len, strTexOffset, TexOffset);
		glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID);
		glBegin( GL_QUADS );			
			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, 0);    //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, 0);    //// B
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, 0, 0);    //// TEMP
			glVertex2i( 0, 0);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, Width, 0);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, 0);  //// B	
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, Width, 0);  //// TEMP	
			glVertex2i( Width, 0);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, Width, Height);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, Height);  //// B	
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, Width, Height);  //// TEMP	
			glVertex2i( Width, Height);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, Height);    //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, Height);	 //// B
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, 0, Height);	 //// TEMP
			glVertex2i( 0, Height);
		glEnd();

		////save the immediate texture result into 
		glBindTexture(_iTextureTarget, result.GetWholeTextureID());
		glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);

	}

	////save the immediate texture result into 
	glBindTexture(_iTextureTarget, result.GetWholeTextureID());
	glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
	glDisable(GL_FRAGMENT_PROGRAM_NV);

	return;
}

////////////////////////////////////////////////////////////////////////////////////////
/// Matrix result(m*n) = Matrix A(m*l) * Matrix B(l*n)
/// Larson-McAllister Matrix Multiplication in 2002 with Register Combiner
/// just Support TEX_RECTANGLE
////////////////////////////////////////////////////////////////////////////////////////
void  clMatMatWithRC(const CDenseMatrixOnGPU& A, const CDenseMatrixOnGPU& B, CDenseMatrixOnGPU& result)
{
	int i;

	//////////////////// Tex0-----DimY*nPass---A--x=nPass,y=Height;
	//////////////////// Tex1-----nPass*DimX---B--x=Width, y=nPass;
	//////////////////// Result---Height*Width-------x=Width, y=Height;
	//// Result Matrix's size
	int Height = A.GetHeight();
	int Width  = B.GetWidth();
	int nPass  = A.GetWidth();
	if(nPass != B.GetHeight())
	{
		AfxMessageBox("For the reason of unmatched matrix size, it's wrong to muliply two matrices!");
		return;
	}
	
	unsigned int _iTextureTarget = A.GetTextureTarget();
	if( _iTextureTarget != GL_TEXTURE_RECTANGLE_NV)
	{
		AfxMessageBox("Error to do matrix-matrix multiplication!");
		return;
	}

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glDisable(GL_DEPTH_TEST);
	glEnable(GL_REGISTER_COMBINERS_NV);

	for(i=0;i<nPass;i++)
	{
		////////////////////////////////////////////// 
		/// Matrix A[m][l]
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(_iTextureTarget, A.GetWholeTextureID());
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(_iTextureTarget);

		//////////////////////////////////////////////
		/// Matrix B[l][n]
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, B.GetWholeTextureID());
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(_iTextureTarget);

		//////////////////////////////////////////////
		///result
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(_iTextureTarget, result.GetWholeTextureID());	
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		glEnable(_iTextureTarget);
			
		glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_TEXTURE0_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
		glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_TEXTURE1_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
		glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
		glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_TEXTURE2_ARB, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
		glFinalCombinerInputNV(GL_VARIABLE_E_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);
		glFinalCombinerInputNV(GL_VARIABLE_F_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);

		glBegin( GL_QUADS );			
			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, 0);    //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, i);    //// B
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, 0, 0);    //// result
			glVertex2i( 0, 0 );

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, 0);	 //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, i);  //// B	
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, Width, 0);    //// result
			glVertex2i( Width, 0 );

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, Height);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, i);  //// B	
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, Width, Height);    //// result
			glVertex2i( Width, Height );

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, Height);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, i);	 //// B
			glMultiTexCoord2dARB(GL_TEXTURE2_ARB, 0, Height);    //// result
			glVertex2i( 0, Height );
		glEnd();
		
		glBindTexture(_iTextureTarget, result.GetWholeTextureID());
		glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
	}
	glDisable(GL_REGISTER_COMBINERS_NV);

	return;
	
}
////////////////////////////////////////////////////////////////////////////////////////
/// Matrix result(m*n) = Matrix A(m*l) * Matrix B(l*n)
/// Larson-McAllister Matrix Multiplication in 2002 with Blend Functions
/// Here, Just need one-pass with N rectangles in the same place
/// Support TEX_RECTANGLE
////////////////////////////////////////////////////////////////////////////////////////
void  clMatMatWithBlend(const CDenseMatrixOnGPU& A, const CDenseMatrixOnGPU& B, CDenseMatrixOnGPU& result)
{
	int i;

	//////////////////// Tex0-----DimY*nPass---A--x=nPass,y=Height;
	//////////////////// Tex1-----nPass*DimX---B--x=Width, y=nPass;
	//////////////////// Result---Height*Width-------x=Width, y=Height;
	//// Result Matrix's size
	int Height = A.GetHeight();
	int Width  = B.GetWidth();
	int nPass  = A.GetWidth();
	if(nPass != B.GetHeight())
	{
		AfxMessageBox("For the reason of unmatched matrix size, it's wrong to muliply two matrices!");
		return;
	}
	
	unsigned int _iTextureTarget = A.GetTextureTarget();

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

	////////////////////////////////////////////// 
	/// Matrix A[m][l]
	glActiveTextureARB(GL_TEXTURE0_ARB);
	glBindTexture(_iTextureTarget, A.GetWholeTextureID());
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(_iTextureTarget);

	//////////////////////////////////////////////
	/// Matrix B[l][n]
	glActiveTextureARB(GL_TEXTURE1_ARB);
    glBindTexture(_iTextureTarget, B.GetWholeTextureID());
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glEnable(_iTextureTarget);

	//// Blend Functions
	glEnable(GL_BLEND);
	/// nPass parallel rectangles in the almost same place
	glBlendFunc(GL_ONE, GL_ZERO);
	glColor4f(1,1,1,1);
	glBegin( GL_QUADS );			
		glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, 0);    //// A
		glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, 0);    //// B
		glVertex2i( 0, 0);

		glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, 0);	 //// A
		glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, 0);  //// B	
		glVertex2i( Width, 0);

		glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, Height);  //// A
		glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, 0);  //// B	
		glVertex2i( Width, Height);

		glMultiTexCoord2dARB(GL_TEXTURE0_ARB, 0, Height);  //// A
		glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, 0);	 //// B
		glVertex2i( 0, Height);
	glEnd();

	glBlendFunc(GL_ONE, GL_ONE);
	for(i=1;i<nPass;i++)
	{
		glBegin( GL_QUADS );			
			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, 0);    //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, i);    //// B
			glVertex2i( 0, 0);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, 0);	 //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, i);  //// B	
			glVertex2i( Width, 0);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, Height);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, Width, i);  //// B	
			glVertex2i( Width, Height);

			glMultiTexCoord2dARB(GL_TEXTURE0_ARB, i, Height);  //// A
			glMultiTexCoord2dARB(GL_TEXTURE1_ARB, 0, i);	 //// B
			glVertex2i( 0, Height);
		glEnd();
	}

	glDisable(GL_BLEND);

	////save the immediate texture result into 
	glBindTexture(_iTextureTarget, result.GetWholeTextureID());
	glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);

	return;
}

⌨️ 快捷键说明

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