www.pudn.com > GPUVision_5-13-05-2.zip > ConvolutionFilter.cpp


 
#include "ConvolutionFilter.h" 
 
using namespace std; 
 
ConvolutionFilter::ConvolutionFilter(float* convolutionData, int width, int height, int numChannels, CGcontext context) : GenericFilter(context){ 
	_width = width; 
	_height = height; 
	_convolutionData = convolutionData; 
 
	int totSize = _width*_height; 
	int hWidth = _width/2; 
	int hHeight = _height/2; 
	char* convProgram = new char[20000]; 
	if(_width == 3 && _height == 3) { 
		_useArray = false; 
        char* tmp = new char[200]; 
        char* mainProg = new char[10000];; 
		mainProg[0] = NULL; 
		// always get the first one for caching purposes 
		sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords)*%f;\n",numChannels,convolutionData[4]); 
		strcat(mainProg,tmp); 
 
		if(convolutionData[0] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( -1,-1))*%f;\n",numChannels,convolutionData[0]); 
			strcat(mainProg,tmp); 
		} 
		if(convolutionData[1] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( 0,-1))*%f;\n",numChannels,convolutionData[1]); 
			strcat(mainProg,tmp); 
		} 
		if(convolutionData[2] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( 1,-1))*%f;\n",numChannels,convolutionData[2]); 
			strcat(mainProg,tmp); 
		} 
 
		if(convolutionData[3] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( -1,0))*%f;\n",numChannels,convolutionData[3]); 
			strcat(mainProg,tmp); 
		} 
		if(convolutionData[5] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( 1,0))*%f;\n",numChannels,convolutionData[5]); 
			strcat(mainProg,tmp); 
		} 
 
		if(convolutionData[6] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( -1,1))*%f;\n",numChannels,convolutionData[6]); 
			strcat(mainProg,tmp); 
		} 
		if(convolutionData[7] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( 0,1))*%f;\n",numChannels,convolutionData[7]); 
			strcat(mainProg,tmp); 
		} 
		if(convolutionData[8] != 0) { 
			sprintf(tmp,"oColor += f%dtexRECT(texture, iCoords+float2( 1,1))*%f;\n",numChannels,convolutionData[8]); 
			strcat(mainProg,tmp); 
		} 
 
 
		sprintf(convProgram,  
			"void main(float2       iCoords   : TEX0,\n" 
			"  float%d iColor : COLOR0,\n" 
			"  uniform samplerRECT texture,\n" 
			"  out float%d oColor : COLOR) {\n"  
			"    oColor = 0;\n    %s\n}", 
			numChannels, 
			numChannels, 
			mainProg); 
		delete tmp; 
		delete mainProg; 
	} else { 
		_useArray = true; 
		sprintf(convProgram,  
			"void main(float2 iCoords   : TEX0,\n" 
			"          uniform samplerRECT texture,\n" 
			"          const uniform float kernel[%d],\n" 
			"          out float%d oColor : COLOR) { \n" 
			"   oColor = 0;\n" 
			"   for(int i = 0; i < %d; i++) {\n" 
			"       for(int j = 0; j < %d; j++) {\n" 
			"           oColor += kernel[%d*i+j]*f%dtexRECT(texture, iCoords+float2(i-%d,j-%d)); \n}\n}\n}\n", 
			totSize, 
			numChannels, 
			width, 
			height, 
			height, 
			numChannels, 
			hWidth, 
			hHeight); 
	} 
 
#if defined(_DEBUG) | defined(DEBUG) 
	cout << "convProgram"<_program); 
//	delete _convolutionData; 
} 
 
 
void ConvolutionFilter::applyFilter(GPUVision *image1){ 
	bool res = image1->IsReset(); 
	bool unBind = false; 
	if(!image1->IsBound()) { 
		image1->Begin(); 
		unBind = true; 
	} 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
	cgGLBindProgram(_program); 
	cgGLSetTextureParameter(_textureParam, image1->IsReset()?image1->GetTextureID():image1->GetRenderedTextureID()); 
	cgGLEnableTextureParameter(_textureParam);	 
	if(_useArray) { 
		cgGLSetParameterArray1f(_kernelParam, 0,_width*_height,_convolutionData); 
	} 
 
	cgGLEnableProfile(_fragmentProfile); 
 
	_DrawFull(image1->GetWidth(), image1->GetHeight()); 
 
	cgGLDisableTextureParameter(_textureParam); 
	cgGLDisableProfile(_fragmentProfile); 
	image1->Flip(); 
	if(unBind) { 
		image1->End(); 
	} 
} 
 
// image2 is what we will use for output size and what we will render to 
void ConvolutionFilter::applyFilter(GPUVision *image1, GPUVision *image2){ 
	bool res = image2->IsReset(); 
	bool unBind = false; 
	if(!image2->IsBound()) { 
		image2->Begin(); 
		unBind = true; 
	} 
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
	cgGLBindProgram(_program); 
	cgGLSetTextureParameter(_textureParam, image1->IsReset()?image1->GetTextureID():image1->GetRenderedTextureID()); 
	cgGLEnableTextureParameter(_textureParam);	 
	if(_useArray) { 
		cgGLSetParameterArray1f(_kernelParam, 0,_width*_height,_convolutionData); 
	} 
 
	cgGLEnableProfile(_fragmentProfile); 
 
	_DrawIntoCoords(image1->GetWidth(), image1->GetHeight(), image2->GetWidth(), image2->GetHeight()); 
 
	cgGLDisableTextureParameter(_textureParam); 
	cgGLDisableProfile(_fragmentProfile); 
	image2->Flip(); 
	if(unBind) { 
		image2->End(); 
	} 
}