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

📄 densematrixvectormultiply.cpp

📁 PDE simulator on GPU.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DenseMatrixVectorMultiply.cpp: implementation of the DenseMatrixVectorMultiply class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "shadow.h"
#include "DenseMatrixVectorMultiply.h"

#include "extgl.h"
#include "FragmentProgram.h"
#include "CommonHW.h"

#include <math.h>
#include "DenseMatrixOnGPU.h"
#include "VectorOnGPU.h"
#include "pbuffer.h"

#include <assert.h>

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

//////////////////////////////////////////////////////////////////////////////
//// New Version on GL_NV_fragment_program
//// Modified Date: 2003/10/23
//// Vector(result) = Matrix(A) * Vector(x)
//// Matrix A -----> General Matrix which is square
//// Support TEX_RECTANGLE
//// Support 1 Channel
//// 4 channels need to load a new fragment program which can process complex
//////////////////////////////////////////////////////////////////////////////
void  DenseMatVecFP(const CDenseMatrixOnGPU& A, const CVectorOnGPU& x, CVectorOnGPU& result)
{
	////////////////////////////////////////////
	///If the size is compatible, then error occurs
	int i, nPass = A.GetDim();
	if(nPass != 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(DenseMatVecFP) for the reason of float precision!");
		return;
		//ShaderID = GlobeShaderID[CL_DENSE_MAT_VECT_2D].ShaderID;
		//LoadFragmentProgramFromFile("..\\matvector.fp", ShaderID);
	}

	//float fTexCoord[2];
	//fTexCoord[0] = Width;
	//fTexCoord[1] = Height;

	ShaderID = GlobeShaderID[CL_DENSE_MAT_VECT_RECT].ShaderID;
	//LoadFragmentProgramFromFile("..\\matvectorRECT.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 len1 = strlen((const char*)strTexPara);
	float TexelPara[4];
	TexelPara[0] = Width;
	TexelPara[1] = 1.0/Width;

	TexelPara[2] = nPass;
	TexelPara[3] = 1.0/nPass;
	
	unsigned char strPassNo[] = "PassNo";
	int len2 = strlen((const char*)strPassNo);
	float PassNo[4];
	
	////##################################################################
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glClear(GL_COLOR_BUFFER_BIT);	

		glEnable(GL_FRAGMENT_PROGRAM_NV);
		glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID);
		glProgramNamedParameter4fvNV(ShaderID,  len1, strTexPara, TexelPara);

		//////////////////////////////////////////////
		///x
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(_iTextureTarget, x.GetTextureID());

		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		result.SetZero();
		pbuffer[i]->EndCapture();
	}

	///Following: Tex_X*Tex_A0 + Tex_X*Tex_A1 + ... + Tex_X*Tex_An-1 
	int WhichPBuffer;
	for(i=0; i<nPass; i++)
	{	
		WhichPBuffer = i%2;
		////##################################################################
		pbuffer[WhichPBuffer]->BeginCapture();
		//////////////////////////////////////////////
		///A[i]
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(_iTextureTarget, A.GetTextureID(i));
		
		/// Transfer the offset variables into the fragment program by names
		/// To Lookup the correct texture position in Texture x
		PassNo[0] = i;
		glProgramNamedParameter4fvNV(ShaderID,  len2, strPassNo, PassNo);
	
		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_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		//glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
		pbuffer[WhichPBuffer]->EndCapture();
	}
/*
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glDisable(GL_FRAGMENT_PROGRAM_NV);
		pbuffer[i]->EndCapture();
	}
*/
	return;
}

//////////////////////////////////////////////////////////////////////////////
//// New Version on GL_NV_fragment_program
//// Modified Date: 2003/12/23
//// Vector(result) = Matrix(A) * Vector(x)
//// Matrix A -----> General Matrix which is square
//// Just Support TEX_RECTANGLE
//// Support 1 Channel, vector x in 1 channel
//// BUT Ai, Ai+1, Ai+2, Ai+3 ---> in RGBA mode, stored in ONE texel
//////////////////////////////////////////////////////////////////////////////
void  MultiDenseMatVecFP(const CDenseMatrixOnGPU& A, const CVectorOnGPU& x, CVectorOnGPU& result)
{
	////////////////////////////////////////////
	///If the size is compatible, then error occurs
	int i, nLen = A.GetDim();
	if(nLen != x.GetVectorLength())
	{
		AfxMessageBox("Error to Operate on Matrix-Vector Multiply for different size!");
		return;
	}

	unsigned int _iTextureTarget = x.GetTextureTarget();
	if(_iTextureTarget == GL_TEXTURE_2D)
	{
		AfxMessageBox("Not support GL_TEXTURE_2D in current system(MultiDenseMatVecFP) for the reason of float precision!");
		return;
		//ShaderID = GlobeShaderID[CL_DENSE_MAT_VECT_2D].ShaderID;
		//LoadFragmentProgramFromFile("..\\matvector.fp", ShaderID);
	}

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

	int Width  = x.GetWidth();
	int Height = x.GetHeight(); 

	float fTexCoord[2];

	fTexCoord[0] = Width;
	fTexCoord[1] = Height;
	ShaderID = GlobeShaderID[CL_MULTI_DENSE_MAT_VECT_RECT].ShaderID;
	//LoadFragmentProgramFromFile("..\\matvectorRECTMulti.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 len1 = strlen((const char*)strTexPara);
	float TexelPara[4];
	TexelPara[0] = Width;
	TexelPara[1] = 1.0/Width;

	TexelPara[2] = nLen;
	TexelPara[3] = 1.0/nLen;
	
	unsigned char strPassNo[] = "PassNo";
	int len2 = strlen((const char*)strPassNo);
	float PassNo[4];

	////##################################################################
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glClear(GL_COLOR_BUFFER_BIT);	

		glEnable(GL_FRAGMENT_PROGRAM_NV);
		glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, ShaderID);
		glProgramNamedParameter4fvNV(ShaderID,  len1, strTexPara, TexelPara);

		//////////////////////////////////////////////
		///x
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(_iTextureTarget, x.GetTextureID());	

		glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		result.SetZero();
		pbuffer[i]->EndCapture();
	}

	int nPass = (int)ceil((float)nLen/4.0);
	///Following: Tex_X*Tex_A0 + Tex_X*Tex_A1 + ... + Tex_X*Tex_An-1 
	int WhichPBuffer;
	for(i=0; i<nPass; i++)
	{	
		WhichPBuffer = i%2;
		////##################################################################
		pbuffer[WhichPBuffer]->BeginCapture();
		//////////////////////////////////////////////
		///A[i]
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(_iTextureTarget, A.GetTextureID(i));
		
		/// Transfer the offset variables into the fragment program by names
		/// To Lookup the correct texture position in Texture x
		PassNo[0] = i*4;
		glProgramNamedParameter4fvNV(ShaderID,  len2, strPassNo, PassNo);
		
		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_TEXTURE1_ARB);
		glBindTexture(_iTextureTarget, result.GetTextureID());
		//glCopyTexSubImage2D(_iTextureTarget, 0, 0, 0, 0, 0, Width, Height);
		pbuffer[WhichPBuffer]->EndCapture();
	}

/*
	for(i=0;i<2;i++)
	{
		pbuffer[i]->BeginCapture();
		glDisable(GL_FRAGMENT_PROGRAM_NV);

⌨️ 快捷键说明

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