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

📄 programcg.cpp

📁 SiftGPU is an implementation of SIFT [1] for GPU. SiftGPU processes pixels parallely to build Gaussi
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//////////////////////////////////////////////////////////////////////////////
//	File:		ProgramCG.cpp
//	Author:		Changchang Wu
//	Description :	implementation of cg related class.
//		class ProgramCG			A simple wrapper of Cg programs
//		class ShaderBagCG		cg shaders for SIFT
//		class FilterCGGL		cg gaussian filters for SIFT
//
//	Copyright (c) 2007 University of North Carolina at Chapel Hill
//	All Rights Reserved
//
//	Permission to use, copy, modify and distribute this software and its
//	documentation for educational, research and non-profit purposes, without
//	fee, and without a written agreement is hereby granted, provided that the
//	above copyright notice and the following paragraph appear in all copies.
//	
//	The University of North Carolina at Chapel Hill make no representations
//	about the suitability of this software for any purpose. It is provided
//	'as is' without express or implied warranty. 
//
//	Please send BUG REPORTS to ccwu@cs.unc.edu
//
////////////////////////////////////////////////////////////////////////////

#if !defined(SIFTGPU_NO_CG)

#include "GL/glew.h"

#include <iostream>
#include <iomanip>
#include <vector>
#include <strstream>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;

#include "GlobalUtil.h"
#include "ProgramCG.h"
#include "GLTexImage.h"
#include "ShaderMan.h"
#include "FrameBufferObject.h"



#if  defined(_WIN32) 
	#pragma comment (lib, "../lib/cg.lib")
	#pragma comment (lib, "../lib/cggl.lib")
#endif

CGcontext	ProgramCG::_Context	=0;
CGprofile	ProgramCG::_FProfile;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

ProgramCG::ProgramCG()
{
	_programID = NULL;
}

ProgramCG::~ProgramCG()
{
	if(_programID) cgDestroyProgram(_programID);
}

ProgramCG::ProgramCG(const char *code, const char** cg_compile_args, CGprofile profile)
{
	_valid = 0;
	_profile = profile;
	GLint epos;
	const char* ati_args[] = {"-po", "ATI_draw_buffers",0}; 
	const char* fp40_args[] = {"-ifcvt", "none","-unroll", "all", GlobalUtil::_UseFastMath? "-fastmath" : 0, 0};
	if(cg_compile_args == NULL) cg_compile_args = GlobalUtil::_IsNvidia? (GlobalUtil::_SupportFP40? fp40_args:NULL) : ati_args;
	_programID = ::cgCreateProgram(_Context, CG_SOURCE, code, profile, NULL, cg_compile_args);
	if(_programID)
	{
		cgGLLoadProgram(_programID );
		//_texParamID = cgGetNamedParameter(_programID, "tex");

		glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &epos);
		if(epos >=0)
		{
			std::cout<<cgGetProgramString(_programID, CG_COMPILED_PROGRAM)<<endl;
			std::cerr<<glGetString(GL_PROGRAM_ERROR_STRING_ARB)<<endl;
		}else
		{
			_valid = 1;
		}
	}else
	{
		std::cerr<<code<<endl;
		glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &epos);
		if(epos >=0)
		{
			std::cout<<cgGetProgramString(_programID, CG_COMPILED_PROGRAM)<<endl;
			std::cerr<<glGetString(GL_PROGRAM_ERROR_STRING_ARB)<<endl;
		}else
		{
			std::cout<<glGetString(GL_PROGRAM_ERROR_STRING_ARB)<<endl;
		}
	}

}

void ProgramCG::ErrorCallback()
{
	CGerror err = cgGetError();
	if(err)
	{
		std::cerr<< cgGetErrorString(err)<<endl;
	}
}


void ProgramCG::InitContext()
{
	if(_Context == 0)
	{
		_Context	= cgCreateContext();
 
		/////////////
		_FProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
		cgGLSetOptimalOptions(_FProfile);

		if(GlobalUtil::_verbose) std::cout<<"Shader Profile: "<<cgGetProfileString(_FProfile)<<endl;

		cgSetErrorCallback(ErrorCallback);
	}
}

void ProgramCG::DestroyContext()
{
	cgDestroyContext(_Context);
}

ShaderBagCG::ShaderBagCG()
{
	ProgramCG::InitContext();
}


int ProgramCG::UseProgram()
{
	if(_programID)
	{
		cgGLEnableProfile(_profile);
		cgGLBindProgram(_programID);

		return 1;
	}else
	{
		return 0;
	}
}

void ShaderBagCG::UnloadProgram()
{

	cgGLUnbindProgram(ProgramCG::_FProfile);
	cgGLDisableProfile(ProgramCG::_FProfile);
}


void ShaderBagCG::LoadFixedShaders()
{
//	s_debug = new ProgramCG( "void main(float4 TexCoord0:TEXCOORD0, out float4 FragColor:COLOR0,"
//		"uniform samplerRECT tex){ gl_FragColor.rg =  gl_TexCoord[0].st;}");

	s_gray = new ProgramCG( 
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float intensity = dot(float3(0.299, 0.587, 0.114), texRECT(tex,TexCoord0.xy ).rgb);\n"
	"FragColor= float4(intensity, intensity, intensity, 1.0);}"	);


	s_sampling = new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float4 cc = texRECT(tex, TexCoord0.xy);	FragColor = float4(cc.rg, 0.0, 0.0);	}"	);


	s_zero_pass = new ProgramCG("void main(out float4 FragColor : COLOR0){FragColor = 0;}");


	ProgramCG * program;
	s_margin_copy = program = new ProgramCG(
	"void main(float4 texCoord0: TEXCOORD0, out float4 FragColor: COLOR0, \n"
	"uniform samplerRECT tex, uniform float2 truncate){\n"
	"FragColor = texRECT(tex, min(texCoord0.xy, truncate)); }");

	_param_margin_copy_truncate = cgGetNamedParameter(*program, "truncate");


	s_grad_pass = new ProgramCG(
	"void main (\n"
	"float4 TexCC : TEXCOORD0, float4 TexLC : TEXCOORD1,\n"
	"float4 TexRC : TEXCOORD2, float4 TexCD : TEXCOORD3, float4 TexCU : TEXCOORD4,\n"
	"out float4 FragData0 : COLOR0, uniform samplerRECT tex)\n"
	"{\n"
	"	float4 v1, v2, gg;\n"
	"	float4 cc  = texRECT(tex, TexCC.xy);\n"
	"	gg.x = texRECT(tex, TexLC.xy).r;\n"
	"	gg.y = texRECT(tex, TexRC.xy).r;\n"
	"	gg.z = texRECT(tex, TexCD.xy).r;\n"
	"	gg.w = texRECT(tex, TexCU.xy).r;\n"
	"	float2 dxdy = (gg.yw - gg.xz); \n"
	"	float grad = 0.5*length(dxdy);\n"
	"	float theta = grad==0? 0: atan2(dxdy.y, dxdy.x);\n"
	"	FragData0 = float4(cc.rg, grad, theta);\n"
	"}\n\0");


	if(GlobalUtil::_SupportFP40)
	{
		//use the packing mode for cpu list reshape and two orientations
		if(GlobalUtil::_MaxOrientation != 2) GlobalUtil::_OrientationPack2 = 0;

		LoadOrientationShader();


		if(GlobalUtil::_DescriptorPPT)		LoadDescriptorShader();

	}else
	{
		s_orientation = program =  new ProgramCG(
		"void main(out float4 FragColor : COLOR0, \n"
	"	uniform samplerRECT fTex, uniform samplerRECT oTex, \n"
	"	uniform float size, \n"
	"	in float2 tpos : TEXCOORD0){\n"
	"	float4 cc = texRECT(fTex, tpos);\n"
	"	float4 oo = texRECT(oTex, cc.rg);\n"
	"	FragColor = float4(cc.rg, oo.a, size);}");  
		_param_orientation_gtex= cgGetNamedParameter(*program, "oTex");
		_param_orientation_size= cgGetNamedParameter(*program, "size");


		///
		GlobalUtil::_FullSupported = 0;
		GlobalUtil::_MaxOrientation = 0;  //0 for simplified version
		GlobalUtil::_DescriptorPPT = 0;
		std::cerr<<"Orientation simplified on this hardware"<<endl;
		std::cerr<<"Descriptor ignored on this hardware"<<endl;
	}


}

void ShaderBagCG::LoadDisplayShaders()
{
	s_copy_key = new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"FragColor.rg= texRECT(tex, TexCoord0.xy).rg; FragColor.ba = float2(0,1);	}");

	//shader used to write a vertex buffer object
	//which is used to draw the quads of each feature
	ProgramCG * program;
	s_vertex_list = program = new ProgramCG(
	"void main(in float4 TexCoord0: TEXCOORD0,\n"
	"uniform float4 sizes, \n"
	"uniform samplerRECT tex, \n"
	"out float4 FragColor: COLOR0){\n"
	"float fwidth = sizes.y; \n"
	"float twidth = sizes.z; \n"
	"float rwidth = sizes.w; \n"
	"float index = 0.1*(fwidth*floor(TexCoord0.y) + TexCoord0.x);\n"
	"float px = fmod(index, twidth);\n"
	"float2 tpos= floor(float2(px, index*rwidth))+0.5;\n"
	"float4 cc = texRECT(tex, tpos );\n"
	"float size = cc.a * 3.0f;//sizes.x;// \n"
	"FragColor.zw = float2(0.0, 1.0);\n"
	"if(any(cc.xy <=0)) {FragColor.xy = cc.xy;}else \n"
	"{\n"
	"	float type = frac(px);\n"
	"	float2 dxy; float s, c;\n"
	"	dxy.x = type < 0.1 ? 0 : ((type <0.5 || type > 0.9)? size : -size);\n"
	"	dxy.y = type < 0.2 ? 0 : ((type < 0.3 || type > 0.7 )? -size :size); \n"
	"	sincos(cc.b, s, c);\n"
	"	FragColor.x = cc.x + c*dxy.x-s*dxy.y;\n"
	"	FragColor.y = cc.y + c*dxy.y+s*dxy.x;}\n"
	"}\n\0");
	/*FragColor = float4(tpos, 0.0, 1.0);}\n\0");*/

	_param_genvbo_size = cgGetNamedParameter(*program, "sizes");


	s_display_gaussian =  new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float r = texRECT(tex, TexCoord0.xy).r;\n"
	"FragColor = float4(r, r, r, 1.0);}");


	s_display_dog =  new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float g = (0.5+20.0*texRECT(tex, TexCoord0.xy).g);\n"
	"FragColor = float4(g, g, g, 1.0);}" );


	s_display_grad = new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float4 cc = texRECT(tex, TexCoord0.xy); FragColor = float4(5.0 * cc.bbb, 1.0); }");


	s_display_keys= new ProgramCG(
	"void main(float4 TexCoord0 : TEXCOORD0, out float4 FragColor : COLOR0, uniform samplerRECT tex){\n"
	"float4 cc = texRECT(tex, TexCoord0.xy);\n"
	"if(cc.r ==1.0) FragColor = float4(1.0, 0, 0,1.0); \n"
	"else {if (cc.r ==0.5) FragColor = float4(0.0,1.0,0.0,1.0);	else discard;}}");	

}

void ShaderBagCG::SetMarginCopyParam(int xmax, int ymax)
{
	float truncate[2] = {xmax - 0.5f , ymax - 0.5f};
	cgGLSetParameter2fv(_param_margin_copy_truncate, truncate);
}


int ShaderBagCG::LoadKeypointShaderMR(float threshold, float edge_threshold)
{
	char buffer[10240];
	float threshold0 = threshold * 0.8f;
	float threshold1 = threshold;
	float threshold2 = (edge_threshold+1)*(edge_threshold+1)/edge_threshold;
	int   max_refine = max(2, GlobalUtil::_SubpixelLocalization);
	ostrstream out(buffer, 10240);

	out <<	"#define THRESHOLD0 " << threshold0 << "\n"
			"#define THRESHOLD1 " << threshold1 << "\n"
			"#define THRESHOLD2 " << threshold2 << "\n"
			"#define MAX_REFINE " << max_refine << "\n";
	out<<
	"void main (\n"
	"float4 TexCC : TEXCOORD0, float4 TexLC : TEXCOORD1,\n"
	"float4 TexRC : TEXCOORD2, float4 TexCD : TEXCOORD3, \n"
	"float4 TexCU : TEXCOORD4, float4 TexLD : TEXCOORD5, \n"
	"float4 TexLU : TEXCOORD6, float4 TexRD : TEXCOORD7,\n"
	"out float4 FragData0 : COLOR0, out float4 FragData1 : COLOR1, \n"
	"uniform samplerRECT tex, uniform samplerRECT texU, uniform samplerRECT texD)\n"
	"{\n"
	"	float4 v1, v2, gg;\n"
	"	float2 TexRU = float2(TexRC.x, TexCU.y); \n"
	"	float4 cc  = texRECT(tex, TexCC.xy);\n"
	"	v1.x = texRECT(tex, TexLC.xy).g;\n"
	"	gg.x = texRECT(tex, TexLC.xy).r;\n"
	"	v1.y = texRECT(tex, TexRC.xy).g;\n"
	"	gg.y = texRECT(tex, TexRC.xy).r;\n"
	"	v1.z = texRECT(tex, TexCD.xy).g;\n"
	"	gg.z = texRECT(tex, TexCD.xy).r;\n"
	"	v1.w = texRECT(tex, TexCU.xy).g;\n"
	"	gg.w = texRECT(tex, TexCU.xy).r;\n"
	"	v2.x = texRECT(tex, TexLD.xy).g;\n"
	"	v2.y = texRECT(tex, TexLU.xy).g;\n"
	"	v2.z = texRECT(tex, TexRD.xy).g;\n"
	"	v2.w = texRECT(tex, TexRU.xy).g;\n"
	"	float2 dxdy = 0.5*(gg.yw - gg.xz); \n"
	"	float grad = length(dxdy);\n"
	"	float theta = grad==0? 0: atan2(dxdy.y, dxdy.x);\n"
	"	FragData0 = float4(cc.rg, grad, theta);\n"
	<<
	"	float dog = 0.0; \n"
	"	FragData1 = float4(0, 0, 0, 0); \n"
	"	float2 v3; float4 v4, v5, v6;\n"
	<<
	"	if( cc.g > THRESHOLD0 && all(cc.gggg > max(v1, v2)))\n"
	"	{\n"
	"		v3.x = texRECT(texU, TexCC.xy).g;\n"
	"		v4.x = texRECT(texU, TexLC.xy).g;\n"
	"		v4.y = texRECT(texU, TexRC.xy).g;\n"
	"		v4.z = texRECT(texU, TexCD.xy).g;\n"
	"		v4.w = texRECT(texU, TexCU.xy).g;\n"
	"		v6.x = texRECT(texU, TexLD.xy).g;\n"
	"		v6.y = texRECT(texU, TexLU.xy).g;\n"
	"		v6.z = texRECT(texU, TexRD.xy).g;\n"
	"		v6.w = texRECT(texU, TexRU.xy).g;\n"
	"		if(cc.g < v3.x || any(cc.gggg<v4.xyzw || cc.gggg<v6.xyzw))return; \n"
	"		v3.y = texRECT(texD, TexCC.xy).g;\n"
	"		v5.x = texRECT(texD, TexLC.xy).g;\n"
	"		v5.y = texRECT(texD, TexRC.xy).g;\n"
	"		v5.z = texRECT(texD, TexCD.xy).g;\n"
	"		v5.w = texRECT(texD, TexCU.xy).g;\n"

⌨️ 快捷键说明

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