00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00033 #include "gl_Cg_shader_system/gl_Cg_shader_system.h"
00034 #include "gl_Cg_shader_system/gl_Cg_code_instructor.h"
00035 #include "gl_Cg_shader_system/gl_Cg_shader.h"
00036 #include "gl_Cg_shader_system/gl_Cg_uniform.h"
00037
00038 #include "gpucalc/log_manager.h"
00039 #include "gpucalc/text_file_loader.h"
00040 #include "gpucalc/application.h"
00041 #include "gpucalc/data.h"
00042 #include "gpucalc/texture.h"
00043 #include "gpucalc/string_util.h"
00044 #include "gpucalc/debugger/debugger.h"
00045
00046
00047
00048 namespace gpucalc
00049 {
00050
00051 GLCgShaderSystem::GLCgShaderSystem(): ShaderSystem(_GLCgShaderSystemObjectName), mIsStarted(false), mActiveShader(0), mShaderMap(), mUniformMap(),
00052 mAcceptableGraphicCoreIDset(), mCodeInstructor(0)
00053 {
00054 }
00055
00056
00057 GLCgShaderSystem::~GLCgShaderSystem()
00058 {
00059 if (mIsStarted)
00060 {
00061 stop();
00062 }
00063 }
00064
00065
00066 Shader * GLCgShaderSystem::create(const std::string & ShaderName)
00067 {
00068 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00069 ShaderMap::iterator i = mShaderMap.find(ShaderName);
00070 if (i != mShaderMap.end())
00071 {
00072 Except<ERR_DUPLICATE_ITEM>(this, "Shader \"" + ShaderName + "\" already exists!", "GLCgShaderSystem::create()", __FILE__, __LINE__);
00073 return 0;
00074 }
00075 else
00076 {
00077 GLCgShader * Result = new GLCgShader(ShaderName, mCgContextID, mCgFragmentProfileID, this);
00078 mShaderMap.insert(std::make_pair(ShaderName, Result));
00079 LogManager::getSingleton().logMessage(this, "Shader object \"" + ShaderName + "\" created.", LML_Trivial);
00080 return Result;
00081 }
00082 }
00083
00084
00085 Shader * GLCgShaderSystem::getShaderByName(const std::string & ShaderName) const
00086 {
00087 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00088 ShaderMap::const_iterator i = mShaderMap.find(ShaderName);
00089 if (i != mShaderMap.end())
00090 {
00091 return i->second;
00092 }
00093 else
00094 {
00095 Except<ERR_ITEM_NOT_FOUND>(this, "Shader \"" + ShaderName + "\" cannot be found!", "GLCgShaderSystem::getShaderbyName()", __FILE__, __LINE__);
00096 }
00097 }
00098
00099
00100 bool GLCgShaderSystem::isShaderCreated(const std::string & ShaderName) const
00101 {
00102 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00103 return (mShaderMap.find(ShaderName) != mShaderMap.end());
00104 }
00105
00106
00107 void GLCgShaderSystem::destroy(Shader * shader)
00108 {
00109 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00110 std::string ShaderName = shader->getObjectName();
00111 if (!removeFromContainer(ShaderName, mShaderMap))
00112 {
00113 Warning<ERR_ITEM_NOT_FOUND>(this, "Shader \"" + ShaderName + "\" cannot be found, destroying anyway.", "GLChShaderSystem::destroy()", __FILE__, __LINE__);
00114 }
00115 delete shader;
00116 LogManager::getSingleton().logMessage(this, "Shader object \"" + ShaderName + "\" destroyed.", LML_Trivial);
00117 }
00118
00119
00120 Uniform * GLCgShaderSystem::create(const Data & data)
00121 {
00122 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00123 std::string UniformName = data.getObjectName();
00124 UniformMap::iterator i = mUniformMap.find(UniformName);
00125 if (i != mUniformMap.end())
00126 {
00127 Except<ERR_DUPLICATE_ITEM>(this, "Uniform variable \"" + UniformName + "\" already exists!", "GLCgShaderSystem::createUniform()", __FILE__, __LINE__);
00128 }
00129 GLCgUniform * result = new GLCgUniform(UniformName);
00130 result->mPointer = data.pointer();
00131 result->mActualLengthGPU = data.getActualLengthCPU() / data.getNumberOfComponents();
00132 result->mNumberOfComponents = data.getNumberOfComponents();
00133 result->mTypeSize = data.getTypeSize();
00134
00135 if (!data.isArray())
00136 {
00137 switch (data.getValueType())
00138 {
00139 case FloatType:
00140 result->mUniformType = static_cast<Uniform::UniformType>(
00141 Uniform::UT_FLOAT_1 + result->getNumberOfComponents() - 1);
00142 break;
00143
00144 case IntType:
00145 case UnsignedIntType:
00146 result->mUniformType = static_cast<Uniform::UniformType>(
00147 Uniform::UT_INT_1 + result->getNumberOfComponents() - 1);
00148 break;
00149
00150 default:
00151 Except<ERR_NOT_IMPLEMENTED>(this, "other ValueTypes is not implemented!",
00152 "GLCgShaderSystem::createUniform()", __FILE__, __LINE__);
00153 break;
00154 }
00155 }
00156 else
00157 {
00158 Except<ERR_INVALIDPARAMS>(this, "this method can work only with uniform data.", "GLCgShaderSystem::create()", __FILE__, __LINE__);
00159 }
00160
00161 mUniformMap.insert(std::make_pair(UniformName, result));
00162 return result;
00163 }
00164
00165
00166 Uniform * GLCgShaderSystem::create(Texture * texture)
00167 {
00168 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00169 UniformMap::iterator i = mUniformMap.find(texture->getObjectName());
00170 if (i != mUniformMap.end())
00171 {
00172 Except<ERR_DUPLICATE_ITEM>(this, "Uniform variable with name \"" + texture->getObjectName() + "\" already exists!",
00173 "GLCgShaderSystem::create()", __FILE__, __LINE__);
00174 return 0;
00175 }
00176 else
00177 {
00178 GLCgUniform * result = new GLCgUniform(texture->getObjectName());
00179 result->mSampler = texture;
00180 result->mUniformType = Uniform::UT_TEX_2;
00181 mUniformMap.insert(std::make_pair(texture->getObjectName(), result));
00182 return result;
00183 }
00184 }
00185
00186
00187 Uniform * GLCgShaderSystem::getUniformByName(const std::string & UniformName) const
00188 {
00189 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00190 UniformMap::const_iterator i = mUniformMap.find(UniformName);
00191 if (i != mUniformMap.end())
00192 {
00193 return i->second;
00194 }
00195 else
00196 {
00197 Except<ERR_ITEM_NOT_FOUND>(this, "Uniform variable with name \"" + UniformName + "\" cannot be found!",
00198 "GLCgShaderSystem::getUniformByName()", __FILE__, __LINE__);
00199 }
00200 }
00201
00202
00203 bool GLCgShaderSystem::isUniformCreated(const std::string & UniformName) const
00204 {
00205 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00206 return (mUniformMap.find(UniformName) != mUniformMap.end());
00207 }
00208
00209
00210 void GLCgShaderSystem::destroy(Uniform * uniform)
00211 {
00212 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00213 std::string UniformName = uniform->getObjectName();
00214 if (!removeFromContainer(UniformName, mUniformMap))
00215 {
00216 Warning<ERR_ITEM_NOT_FOUND>(this, "Uniform \"" + UniformName + "\" cannot be found, destroying anyway.", "GLChShaderSystem::destroy()", __FILE__, __LINE__);
00217 }
00218 delete uniform;
00219 LogManager::getSingleton().logMessage(this, "Uniform variable \"" + UniformName + "\" destroyed.", LML_Trivial);
00220 }
00221
00222
00223 void GLCgShaderSystem::bind(Shader * shader)
00224 {
00225 assert(shader && "Shader does not created!!!");
00226 if (shader != mActiveShader)
00227 {
00228 GLCgShader * CgShader = static_cast<GLCgShader *>(shader);
00229 cgGLBindProgram(CgShader->mCgFragmentProgramID);
00230 mActiveShader = shader;
00231 }
00232 }
00233
00234
00235 void GLCgShaderSystem::unbind(Shader * shader)
00236 {
00237 assert(shader && "Shader does not created!!!");
00238 if (shader == mActiveShader)
00239 {
00240 GLCgShader * CgShader = static_cast<GLCgShader *>(shader);
00241 cgGLUnbindProgram(CgShader->mCgFragmentProfileID);
00242 mActiveShader = 0;
00243 }
00244 }
00245
00246
00247 Shader * GLCgShaderSystem::getActiveShader() const
00248 {
00249 return mActiveShader;
00250 }
00251
00252
00253 CGcontext LocalCGContext;
00254
00255
00256 void cgErrorCallBackFunction()
00257 {
00258 CGerror LastError = cgGetError();
00259 if (LastError != CG_NO_ERROR)
00260 {
00261 Except<ERR_RENDERINGAPI_ERROR>(Object(_ShaderSystemClassName, _GLCgShaderSystemObjectName),
00262 std::string(cgGetErrorString(LastError)) + cgGetLastListing(LocalCGContext), "somewhere...", __FILE__, __LINE__);
00263 }
00264 }
00265
00266
00267 void GLCgShaderSystem::start()
00268 {
00269 if (mIsStarted) return;
00271 mCgContextID = cgCreateContext();
00272 LocalCGContext = mCgContextID;
00273 cgSetErrorCallback(cgErrorCallBackFunction);
00274 mCgFragmentProfileID = cgGLGetLatestProfile(CG_GL_FRAGMENT);
00275 cgGLSetOptimalOptions(mCgFragmentProfileID);
00276
00277
00278 mIsStarted = true;
00279 this->addAcceptableGraphicCoreID("GLGraphicCore");
00280 LogManager::getSingleton().logMessage(this, "---===========================================---");
00281 LogManager::getSingleton().logMessage(this, "---=== GL Cg Shader system started ===---");
00282 LogManager::getSingleton().logMessage(this, "---===========================================---");
00283
00284 if (debugger::Debugger::getSingletonPtr() != 0)
00285 {
00286 mCodeInstructor = new debugger::GLCgCodeInstructor();
00287 debugger::Debugger::getSingleton().addCodeInstructor(mCodeInstructor);
00288 }
00289 }
00290
00291
00292 void GLCgShaderSystem::stop()
00293 {
00294 assert(mIsStarted && "GLCgShaderSystem is not started!!!");
00296 clearContainer(mShaderMap);
00297 clearContainer(mUniformMap);
00298
00299 LogManager::getSingleton().logMessage(this, "---===========================================---");
00300 LogManager::getSingleton().logMessage(this, "---=== GL Cg Shader system stopped ===---");
00301 LogManager::getSingleton().logMessage(this, "---===========================================---");
00302 mIsStarted = false;
00303
00304 if (debugger::Debugger::getSingletonPtr() != 0)
00305 {
00306
00307 delete mCodeInstructor;
00308 }
00309 }
00310
00311
00312 bool GLCgShaderSystem::isAcceptCore(const GraphicCore * Core) const
00313 {
00314 return (mAcceptableGraphicCoreIDset.find(Core->getObjectName()) != mAcceptableGraphicCoreIDset.end());
00315 }
00316
00317
00318 bool GLCgShaderSystem::isAcceptFileExtension(const std::string & FileExtension) const
00319 {
00320 return auxillary::StringUtil::toLower(FileExtension) == std::string("cg");
00321 }
00322
00323
00324 void GLCgShaderSystem::addAcceptableGraphicCoreID(const std::string & GraphicCoreID)
00325 {
00326 mAcceptableGraphicCoreIDset.insert(GraphicCoreID);
00327 }
00328
00329
00330 debugger::CodeInstructor * GLCgShaderSystem::getCodeInstructor() const
00331 {
00332 return mCodeInstructor;
00333 }
00334 }