284 lines
7.2 KiB
C++
284 lines
7.2 KiB
C++
/* This file is part of the Pangolin Project.
|
|
* http://github.com/stevenlovegrove/Pangolin
|
|
*
|
|
* Copyright (c) 2011 Steven Lovegrove
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following
|
|
* conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
|
|
// Cg includes
|
|
#include <Cg/cg.h>
|
|
#include <Cg/cgGL.h>
|
|
|
|
#include "gl.h"
|
|
|
|
#ifdef HAVE_TOON
|
|
#include <TooN/TooN.h>
|
|
#endif // HAVE_TOON
|
|
|
|
namespace pangolin
|
|
{
|
|
|
|
////////////////////////////////////////////////
|
|
// Interface
|
|
////////////////////////////////////////////////
|
|
|
|
/// Lightweight object wrapper for NVidia Cg Shader program objects.
|
|
class CgProgram
|
|
{
|
|
friend class CgLoader;
|
|
public:
|
|
void SetUniform(const std::string& name, GlTexture& tex);
|
|
void SetUniform(const std::string& name, float f);
|
|
void SetUniform(const std::string& name, float v0, float v1);
|
|
void SetUniform(const std::string& name, float v0, float v1, float v2, float v3);
|
|
|
|
#ifdef HAVE_TOON
|
|
void SetUniform(const std::string& name, const TooN::Vector<2>& v );
|
|
void SetUniform(const std::string& name, const TooN::Vector<3>& v );
|
|
|
|
template <int R, int C>
|
|
void SetUniform(const std::string& name, const TooN::Matrix<R,C>& M );
|
|
#endif
|
|
|
|
void UpdateParams();
|
|
|
|
protected:
|
|
CGprogram mProg;
|
|
CGcontext mContext;
|
|
CGprofile mProfile;
|
|
};
|
|
|
|
class CgLoader
|
|
{
|
|
public:
|
|
CgLoader();
|
|
~CgLoader();
|
|
|
|
// Call AFTER glewInit (or similar)
|
|
void Initialise();
|
|
|
|
CgProgram LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader );
|
|
|
|
void EnableProgram(CgProgram program);
|
|
void DisablePrograms();
|
|
|
|
void RenderDummyQuad();
|
|
void RenderDummyQuadWithTexCoords(int w, int h);
|
|
|
|
protected:
|
|
CGcontext mContext;
|
|
CGprofile mFragmentProfile;
|
|
CGprofile mVertexProfile;
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
// Implementation
|
|
////////////////////////////////////////////////
|
|
|
|
inline bool cgOkay()
|
|
{
|
|
CGerror error;
|
|
const char *string = cgGetLastErrorString(&error);
|
|
|
|
if (error != CG_NO_ERROR) {
|
|
std::cout << "CG Error: " << string << std::endl;
|
|
// assert(0);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline CgLoader::CgLoader()
|
|
:mContext(0)
|
|
{
|
|
}
|
|
|
|
inline CgLoader::~CgLoader()
|
|
{
|
|
if(mContext)
|
|
{
|
|
// Destroying context destroys all programs associated with it
|
|
cgDestroyContext(mContext);
|
|
}
|
|
}
|
|
|
|
|
|
inline void CgLoader::Initialise()
|
|
{
|
|
mContext = cgCreateContext();
|
|
cgSetParameterSettingMode(mContext, CG_DEFERRED_PARAMETER_SETTING);
|
|
cgOkay();
|
|
|
|
mFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
|
cgGLSetOptimalOptions(mFragmentProfile);
|
|
cgOkay();
|
|
|
|
mVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
|
|
cgGLSetOptimalOptions(mVertexProfile);
|
|
cgOkay();
|
|
}
|
|
|
|
inline CgProgram CgLoader::LoadProgramFromFile(const std::string& file, const std::string& function, bool isVertexShader )
|
|
{
|
|
if( !mContext ) {
|
|
Initialise();
|
|
}
|
|
|
|
CgProgram prog;
|
|
|
|
prog.mContext = mContext;
|
|
prog.mProfile = isVertexShader ? mVertexProfile : mFragmentProfile;
|
|
prog.mProg = cgCreateProgramFromFile( prog.mContext, CG_SOURCE, file.c_str(), prog.mProfile, function.c_str(), NULL);
|
|
|
|
if( !cgOkay() )
|
|
{
|
|
std::cout << cgGetLastListing(mContext) << std::endl;
|
|
assert(0);
|
|
}
|
|
|
|
cgGLLoadProgram(prog.mProg);
|
|
if( !cgOkay() )
|
|
{
|
|
const char* err = cgGetProgramString( prog.mProg, CG_COMPILED_PROGRAM );
|
|
int pos;
|
|
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
|
|
std::cout << err << std::endl;
|
|
std::cout << "@ " << pos << std::endl;
|
|
assert(0);
|
|
}
|
|
return prog;
|
|
}
|
|
|
|
inline void CgLoader::EnableProgram(CgProgram program)
|
|
{
|
|
cgGLBindProgram(program.mProg);
|
|
cgGLEnableProfile(program.mProfile);
|
|
cgOkay();
|
|
}
|
|
|
|
inline void CgLoader::DisablePrograms()
|
|
{
|
|
cgGLDisableProfile(mFragmentProfile);
|
|
cgGLDisableProfile(mVertexProfile);
|
|
}
|
|
|
|
inline void CgLoader::RenderDummyQuad()
|
|
{
|
|
glBegin(GL_QUADS);
|
|
glVertex2d(-1,1);
|
|
glVertex2d(1,1);
|
|
glVertex2d(1,-1);
|
|
glVertex2d(-1,-1);
|
|
glEnd();
|
|
}
|
|
|
|
inline void CgLoader::RenderDummyQuadWithTexCoords(int w, int h)
|
|
{
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2f(0, 0);
|
|
glVertex2d(-1,-1);
|
|
glTexCoord2f(w, 0);
|
|
glVertex2d(1,-1);
|
|
glTexCoord2f(w, h);
|
|
glVertex2d(1,1);
|
|
glTexCoord2f(0, h);
|
|
glVertex2d(-1,1);
|
|
glEnd();
|
|
}
|
|
|
|
void CgProgram::SetUniform(const std::string& name, float f)
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgSetParameter1f( p, f );
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
void CgProgram::SetUniform(const std::string& name, GlTexture& tex)
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgGLSetTextureParameter(p, tex.tid );
|
|
cgGLEnableTextureParameter(p);
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
void CgProgram::SetUniform(const std::string& name, float v0, float v1, float v2, float v3)
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgGLSetParameter4f(p, v0,v1,v2,v3);
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
void CgProgram::SetUniform(const std::string& name, float v0, float v1)
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgGLSetParameter2f(p, v0,v1);
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
#ifdef HAVE_TOON
|
|
void CgProgram::SetUniform(const std::string& name, const TooN::Vector<2>& v )
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgGLSetParameter2f(p, v[0],v[1] );
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
void CgProgram::SetUniform(const std::string& name, const TooN::Vector<3>& v )
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
cgGLSetParameter3f(p, v[0],v[1],v[2] );
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
template <int R, int C>
|
|
void CgProgram::SetUniform(const std::string& name, const TooN::Matrix<R,C>& M )
|
|
{
|
|
CGparameter p = cgGetNamedParameter( mProg, name.c_str());
|
|
float Mdata[R*C];
|
|
|
|
int i=0;
|
|
for( int r=0; r<R; ++r )
|
|
for( int c=0; c<C; ++c )
|
|
Mdata[i++] = (float)(M[r][c]);
|
|
|
|
cgGLSetMatrixParameterfr(p, Mdata );
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
#endif
|
|
|
|
void CgProgram::UpdateParams()
|
|
{
|
|
cgUpdateProgramParameters(mProg);
|
|
}
|
|
|
|
|
|
}
|