📄 programcg.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// 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 + -