00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef PANGOLIN_CG_H
00029 #define PANGOLIN_CG_H
00030
00031 #include <sstream>
00032 #include <algorithm>
00033
00034
00035 #include <Cg/cg.h>
00036 #include <Cg/cgGL.h>
00037
00038 #include "gl.h"
00039
00040 #ifdef HAVE_TOON
00041 #include <TooN/TooN.h>
00042 #endif // HAVE_TOON
00043
00044 namespace pangolin
00045 {
00046
00048
00050
00051 struct CgProgram
00052 {
00053 CGprogram mProg;
00054 CGcontext mContext;
00055 CGprofile mProfile;
00056
00057 void SetUniform(const std::string& name, GlTexture& tex);
00058 void SetUniform(const std::string& name, float f);
00059
00060 #ifdef HAVE_TOON
00061 void SetUniform(const std::string& name, const TooN::Vector<2>& v );
00062 void SetUniform(const std::string& name, const TooN::Vector<3>& v );
00063
00064 template <int R, int C>
00065 void SetUniform(const std::string& name, const TooN::Matrix<R,C>& M );
00066 #endif
00067
00068 void UpdateParams();
00069 };
00070
00071 struct CgLoader
00072 {
00073 CgLoader();
00074 ~CgLoader();
00075
00076
00077 void Initialise();
00078
00079 CgProgram LoadProgram(const std::string& file, const std::string& function, bool isVertexShader );
00080
00081 void EnableProgram(CgProgram program);
00082 void DisablePrograms();
00083
00084 void RenderDummyQuad();
00085 void RenderDummyQuadWithTexCoords(int w, int h);
00086
00087 CGcontext mContext;
00088 CGprofile mFragmentProfile;
00089 CGprofile mVertexProfile;
00090 };
00091
00092
00093
00094
00096
00098
00099 inline bool cgOkay()
00100 {
00101 CGerror error;
00102 const char *string = cgGetLastErrorString(&error);
00103
00104 if (error != CG_NO_ERROR)
00105 {
00106 std::cout << "CG Error: " << string << std::endl;
00107
00108 return false;
00109 }
00110 return true;
00111 }
00112
00113 inline CgLoader::CgLoader()
00114 :mContext(0)
00115 {
00116 }
00117
00118 inline CgLoader::~CgLoader()
00119 {
00120 if(mContext)
00121 {
00122
00123 cgDestroyContext(mContext);
00124 }
00125 }
00126
00127
00128 inline void CgLoader::Initialise()
00129 {
00130 mContext = cgCreateContext();
00131 cgSetParameterSettingMode(mContext, CG_DEFERRED_PARAMETER_SETTING);
00132 cgOkay();
00133
00134 mFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
00135 cgGLSetOptimalOptions(mFragmentProfile);
00136 cgOkay();
00137
00138 mVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
00139 cgGLSetOptimalOptions(mVertexProfile);
00140 cgOkay();
00141 }
00142
00143 inline CgProgram CgLoader::LoadProgram(const std::string& file, const std::string& function, bool isVertexShader )
00144 {
00145 if( !mContext )
00146 Initialise();
00147
00148 CgProgram prog;
00149
00150 prog.mContext = mContext;
00151 prog.mProfile = isVertexShader ? mVertexProfile : mFragmentProfile;
00152 prog.mProg = cgCreateProgramFromFile( prog.mContext, CG_SOURCE, file.c_str(), prog.mProfile, function.c_str(), NULL);
00153
00154 if( !cgOkay() )
00155 {
00156 std::cout << cgGetLastListing(mContext) << std::endl;
00157 assert(0);
00158 }
00159
00160 cgGLLoadProgram(prog.mProg);
00161 if( !cgOkay() )
00162 {
00163 const char* err = cgGetProgramString( prog.mProg, CG_COMPILED_PROGRAM );
00164 int pos;
00165 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
00166 std::cout << err << std::endl;
00167 std::cout << "@ " << pos << std::endl;
00168 assert(0);
00169 }
00170 return prog;
00171 }
00172
00173 inline void CgLoader::EnableProgram(CgProgram program)
00174 {
00175 cgGLBindProgram(program.mProg);
00176 cgGLEnableProfile(program.mProfile);
00177 cgOkay();
00178 }
00179
00180 inline void CgLoader::DisablePrograms()
00181 {
00182 cgGLDisableProfile(mFragmentProfile);
00183 cgGLDisableProfile(mVertexProfile);
00184 }
00185
00186 inline void CgLoader::RenderDummyQuad()
00187 {
00188 glBegin(GL_QUADS);
00189 glVertex2d(-1,1);
00190 glVertex2d(1,1);
00191 glVertex2d(1,-1);
00192 glVertex2d(-1,-1);
00193 glEnd();
00194 }
00195
00196 inline void CgLoader::RenderDummyQuadWithTexCoords(int w, int h)
00197 {
00198 glBegin(GL_QUADS);
00199 glTexCoord2f(0, 0);
00200 glVertex2d(-1,-1);
00201 glTexCoord2f(w, 0);
00202 glVertex2d(1,-1);
00203 glTexCoord2f(w, h);
00204 glVertex2d(1,1);
00205 glTexCoord2f(0, h);
00206 glVertex2d(-1,1);
00207 glEnd();
00208 }
00209
00210 void CgProgram::SetUniform(const std::string& name, float f)
00211 {
00212 CGparameter p = cgGetNamedParameter( mProg, name.c_str());
00213 cgSetParameter1f( p, f );
00214 cgUpdateProgramParameters(mProg);
00215 }
00216
00217 void CgProgram::SetUniform(const std::string& name, GlTexture& tex)
00218 {
00219 CGparameter p = cgGetNamedParameter( mProg, name.c_str());
00220 cgGLSetTextureParameter(p, tex.tid );
00221 cgGLEnableTextureParameter(p);
00222 cgUpdateProgramParameters(mProg);
00223 }
00224
00225 #ifdef HAVE_TOON
00226 void CgProgram::SetUniform(const std::string& name, const TooN::Vector<2>& v )
00227 {
00228 CGparameter p = cgGetNamedParameter( mProg, name.c_str());
00229 cgGLSetParameter2f(p, v[0],v[1] );
00230 cgUpdateProgramParameters(mProg);
00231 }
00232
00233 void CgProgram::SetUniform(const std::string& name, const TooN::Vector<3>& v )
00234 {
00235 CGparameter p = cgGetNamedParameter( mProg, name.c_str());
00236 cgGLSetParameter3f(p, v[0],v[1],v[2] );
00237 cgUpdateProgramParameters(mProg);
00238 }
00239
00240 template <int R, int C>
00241 void CgProgram::SetUniform(const std::string& name, const TooN::Matrix<R,C>& M )
00242 {
00243 CGparameter p = cgGetNamedParameter( mProg, name.c_str());
00244 float Mdata[R*C];
00245
00246 int i=0;
00247 for( int r=0; r<R; ++r )
00248 for( int c=0; c<C; ++c )
00249 Mdata[i++] = (float)(M[r][c]);
00250
00251 cgGLSetMatrixParameterfr(p, Mdata );
00252 cgUpdateProgramParameters(mProg);
00253 }
00254 #endif
00255
00256 void CgProgram::UpdateParams()
00257 {
00258 cgUpdateProgramParameters(mProg);
00259 }
00260
00261
00262 }
00263
00264 #endif // PANGOLIN_CG_H