Show program-glsl.cpp syntax highlighted
/***************************************************************************
program-glsl.cpp - GLSL programs
-------------------
last modify date : Mon Sep 20 2004
last modify : GLSL manager
l.m. copyright : (C) 2004 by Arcadia Design s.r.l.
email : Dario Deledda (penguindark@hotmail.com)
***************************************************************************
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is the NeoEngine, NeoDevOpenGL, shader-arb.h
The Initial Developer of the Original Code is Mattias Jansson.
Portions created by Mattias Jansson are Copyright (C) 2004
Reality Rift Studios. All Rights Reserved.
Contributors: Dario Deledda (penguindark@hotmail.com)
***************************************************************************/
#include "program-glsl.h"
#include <neoengine/light.h>
#include <neoengine/scenenode.h>
#include <neoengine/strutil.h>
#include <neoengine/logstream.h>
#include <neoengine/file.h>
#include <neoengine/filemanager.h>
//#include <GL/glu.h>
#include <sstream>
using namespace std;
using namespace NeoEngine;
namespace NeoOGL
{
bool ProgramGLSL::SetTextureModeMatrix(NeoEngine::Matrix &inMatrix){
// Set up the depth texture projection
glMatrixMode( GL_TEXTURE );
glLoadIdentity();
glTranslatef( 0.5f, 0.5f, 0.5f ); // Offset
glScalef( 0.5f, 0.5f, 0.5f ); // Bias
neoglMultMatrixf( (float*) m_pkDevice->lightProjectionMatrix );
neoglMultMatrixf( (float*) m_pkDevice->lightViewMatrix );
NeoEngine::Matrix nativeView = m_pkDevice->GetViewMatrix();
nativeView=nativeView.Inverse();
neoglMultMatrixf( (float*) nativeView );
glMatrixMode( GL_MODELVIEW );
return true;
}
bool ProgramGLSL::Build( const std::string *pstrSourceV ,
const std::string *pstrSourceF ,
const std::string *pstrSourceG ){
bool bFIsCompiled=false;
bool bVIsCompiled=false;
bool bGIsCompiled=false;
bool bIsLinked=false;
if ( !pstrSourceF && !pstrSourceF && !pstrSourceG){
return false;
}
if (pstrSourceF)
bFIsCompiled=this->CompileFrag(pstrSourceF);
if (pstrSourceV)
bVIsCompiled=this->CompileVert(pstrSourceV);
if (pstrSourceG)
bGIsCompiled=this->CompileGeometry(pstrSourceG);
bIsLinked=this->Link();
if (pstrSourceG){
if (bFIsCompiled && bVIsCompiled && bGIsCompiled && bIsLinked){
return true;
}
}else if ( bFIsCompiled && bVIsCompiled && bIsLinked ) {
return true;
}
return false;
}
bool ProgramGLSL::LoadNode( unsigned int uiFlags )
{
if( !m_pkFile || !m_pkFile->IsValid() )
return false;
unsigned int uiSize = m_pkFile->GetSize();
char *pcSource = new char[ uiSize + 1 ];
m_pkFile->Read( pcSource, uiSize );
pcSource[ uiSize ] = 0;
m_strSource = pcSource;
delete [] pcSource;
SetName( File::ExtractBaseFileName( m_pkFile->GetName() ) );
return true;
return false;
}
// return true if the parameter binded is a system parameter
inline bool BindParameterGLSLP( Device *pkDevice, GLenum eTarget, ShaderParam *pkParam, RenderPrimitive *pkPrimitive ,GLhandleARB hProgram)
{
static float afIdentity[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
float afVal[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
//unsigned int uiLight = pkDevice->m_uiCurLight + pkParam->m_uiLight;
unsigned int uiLight = 0;
//
// Standard parameter binding
//
// Model matrix
if(pkParam->m_sName=="NeoModelMatrix")
{
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(pkPrimitive->m_kModelMatrix.m_aafMatrix[0][0]));
return true;
}
// View matrix
if(pkParam->m_sName=="NeoViewMatrix")
{
Matrix kMat = (pkDevice->GetViewMatrix());
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(kMat.m_aafMatrix[0][0]));
return true;
}
// Projection matrix
if(pkParam->m_sName=="NeoProjectionMatrix")
{
Matrix kMat = pkDevice->GetProjectionMatrix();
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(kMat.m_aafMatrix[0][0]));
return true;
}
// Model view matrix
if(pkParam->m_sName=="NeoModelViewMatrix")
{
Matrix kMat( pkDevice->GetViewMatrix() * pkPrimitive->m_kModelMatrix );
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(kMat.m_aafMatrix[0][0]));
return true;
}
// Model view Projection matrix
if(pkParam->m_sName=="NeoModelViewProjMatrix")
{
Matrix kMat( ( pkDevice->GetProjectionMatrix() * pkDevice->GetViewMatrix() ) * pkPrimitive->m_kModelMatrix );
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(kMat.m_aafMatrix[0][0]));
return true;
}
// Inverse model matrix
if(pkParam->m_sName=="NeoInvViewMatrix")
{
Matrix kMat( pkPrimitive->m_kInvModelMatrix );
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str()),
1, false,&(kMat.m_aafMatrix[0][0]));
return true;
}
// link the texture unit to the GLSL sampler
for (unsigned int uiIndex=0; uiIndex < pkDevice->m_uiNumTMUs ; uiIndex++){
// set the texture unit
char txtunit[8];
sprintf(txtunit,"text%d",uiIndex);
if( strcmp(pkParam->m_sName.c_str(),txtunit) == 0 ){
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, txtunit),uiIndex );
return false;
}
}
switch( pkParam->m_eType )
{
/*
// bool type not yet supported
case ShaderParam::GLSL_BOOL:
{
break;
}
case ShaderParam::GLSL_BOOL2:
{
break;
}
case ShaderParam::GLSL_BOOL3:
{
break;
}
case ShaderParam::GLSL_BOOL4:
{
break;
}
*/
case ShaderParam::GLSL_SMP1:
{
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt);
break;
}
case ShaderParam::GLSL_SMP2:
{
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt);
break;
}
case ShaderParam::GLSL_SMP3:
{
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt);
break;
}
case ShaderParam::GLSL_SMPC:
{
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt);
break;
}
case ShaderParam::GLSL_MAT2:
{
fpneoglUniformMatrix2fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
1, false,(GLfloat*)(pkParam->m_Value.m_pkMatrix[0][0]) );
break;
}
case ShaderParam::GLSL_MAT3:
{
fpneoglUniformMatrix3fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
1, false,(GLfloat*)(pkParam->m_Value.m_pkMatrix[0][0]) );
break;
}
case ShaderParam::GLSL_MAT4:
{
fpneoglUniformMatrix4fvARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
1, false,(GLfloat*)(pkParam->m_Value.m_pkMatrix[0][0]) );
break;
}
case ShaderParam::GLSL_INT:
{
fpneoglUniform1iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt);
break;
}
case ShaderParam::GLSL_INT2:
{
fpneoglUniform2iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt2[0],
pkParam->m_Value.m_pkInt2[1]);
break;
}
case ShaderParam::GLSL_INT3:
{
fpneoglUniform3iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt3[0],
pkParam->m_Value.m_pkInt3[1],
pkParam->m_Value.m_pkInt3[2]);
break;
}
case ShaderParam::GLSL_INT4:
{
fpneoglUniform4iARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkInt4[0],
pkParam->m_Value.m_pkInt4[1],
pkParam->m_Value.m_pkInt4[2],
pkParam->m_Value.m_pkInt4[3]);
break;
}
case ShaderParam::GLSL_FLOAT:
{
fpneoglUniform1fARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkFloat);
break;
}
case ShaderParam::GLSL_FLOAT2:
{
fpneoglUniform2fARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkFloat2[0],
pkParam->m_Value.m_pkFloat2[1]);
break;
}
case ShaderParam::GLSL_FLOAT3:
{
fpneoglUniform3fARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkFloat3[0],
pkParam->m_Value.m_pkFloat3[1],
pkParam->m_Value.m_pkFloat3[2]);
break;
}
case ShaderParam::GLSL_FLOAT4:
{
fpneoglUniform4fARB(fpneoglGetUniformLocationARB(hProgram, pkParam->m_sName.c_str() ),
pkParam->m_Value.m_pkFloat4[0],
pkParam->m_Value.m_pkFloat4[1],
pkParam->m_Value.m_pkFloat4[2],
pkParam->m_Value.m_pkFloat4[3]);
break;
}
}
return false;
}
ProgramGLSL::ProgramGLSL( Device *pkDevice, SHADERTYPE eType, const std::string &rstrName,
NeoEngine::ShaderPool *pkShaderPool, FileManager *pkFileManager) :
NeoOGL::Shader( pkDevice, eType,rstrName, pkShaderPool, pkFileManager ),
m_uiShader( 0 ),
m_eType( eType == GLSLPROGRAM )
{
m_eGeometryInpType = NeoEngine::Shader::NGL_TRIANGLES;
m_eGeometryOutType = NeoEngine::Shader::NGL_TRIANGLE_STRIP;
m_iGeometryOutVertex = 0;
m_vhVS.clear();
m_vhFS.clear();
m_vhGS.clear();
m_hProgram=0;
}
ProgramGLSL::~ProgramGLSL()
{
if( m_hProgram )
fpneoglDeleteObjectARB(m_hProgram);
}
/*
#define pprintOpenGLError() pprintOglError(__FILE__, __LINE__)
int pprintOglError(char *file, int line)
{
//
// Returns 1 if an OpenGL error occurred, 0 otherwise.
//
GLenum glErr;
int retCode = 0;
glErr = glGetError();
while (glErr != GL_NO_ERROR)
{
string err=(char*)gluErrorString(glErr);
neolog << LogLevel( DEBUG ) << "file :"<<file << endl;
neolog << LogLevel( DEBUG ) << "line :"<<(int)line << endl;
neolog << LogLevel( DEBUG ) << "glError :"<<err<< std::endl;
retCode = 1;
glErr = glGetError();
}
return retCode;
}
*/
//
// Print out the information log for a shader object or a program object
//
void pprintInfoLog(GLhandleARB obj)
{
int infologLength = 0;
int charsWritten = 0;
GLcharARB *infoLog;
fpneoglGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&infologLength);
if (infologLength > 0)
{
infoLog = new GLcharARB[infologLength];
if (infoLog == NULL)
{
neolog << LogLevel( ERROR ) << "ERROR: Could not allocate InfoLog buffer"<<std::endl;
exit(1);
}
fpneoglGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
neolog << LogLevel( DEBUG ) << infoLog<<std::endl;
delete[] infoLog;
}
}
bool ProgramGLSL::BindParamGLSL(const string& inString){
string lString=inString;
string uniforms;
// delete all comments type //
string::size_type pos=0;
string::size_type pos1=0;
while ( ( pos = lString.find("//",pos)) != string::npos ){
pos1=pos;
pos1 = lString.find('\n',pos1);
if (pos1 != string::npos && (pos1>pos)){
lString.erase(pos, pos1-pos+1);
pos=0;
}
}
// delete all comments type /* */
pos=0;
while ( ( pos = lString.find("/*",pos)) != string::npos ){
pos1=pos+2;
pos1 = lString.find("*/",pos1);
if (pos1 != string::npos && (pos1>pos)){
lString.erase(pos, pos1-pos+2);
pos=0;
}else{
break;
}
}
// cout << lString<< endl;
neolog << "=======Parsing GLSL Uniform variabiles Start==========="<<endl;
// hold only uniform parameteres
pos=0;
while ( ( pos = lString.find("uniform",pos)) != string::npos ){
pos1=pos+2;
pos1 = lString.find(";",pos1);
if (pos1 != string::npos && (pos1>pos)){
neolog<< lString.substr(pos, pos1-pos)<<endl;
match_uniform(lString.substr(pos, pos1-pos));
neolog << endl;
pos=pos1+1;
}else{
break;
}
}
// hold only attribute parameteres
pos=0;
while ( ( pos = lString.find("attribute",pos)) != string::npos ){
pos1=pos+2;
pos1 = lString.find(";",pos1);
if (pos1 != string::npos && (pos1>pos)){
neolog<< lString.substr(pos, pos1-pos)<<endl;
match_attrib(lString.substr(pos, pos1-pos));
neolog << endl;
pos=pos1+1;
}else{
break;
}
}
neolog << "=======Parsing GLSL Uniform variabiles End==========="<<endl;
return true;
}
void ProgramGLSL::deleteSpace(string &inString){
string::size_type pos=0;
string::size_type len=1;
while ((pos = inString.find_first_of(" ",pos)) != string::npos){
inString.erase(pos,len);
}
}
bool ProgramGLSL::match_attrib(const string& inString){
string lString=inString;
string::size_type pos=0;
string::size_type pos1=0;
string::size_type pos2=0;
string attrib_type;
vector<string> names;
pos=0;
// delete the "attrib" word
if ( ( pos = lString.find(" ",pos)) != string::npos ){
lString.erase(0,pos+1);
// cut the type of the uniform(s)
pos=0;
pos1=pos;
if ( ( pos1 = lString.find(" ",pos1)) != string::npos ){
attrib_type=lString.substr(pos,pos1-pos);
deleteSpace(attrib_type);
lString.erase(pos,pos1-pos);
neolog << "Attrib type:"<< attrib_type << endl;
pos=0;
while ( ( pos1 = lString.find(",",pos)) != string::npos ){
string var=lString.substr(pos,pos1-pos);
deleteSpace(var);
neolog << "var:"<<var << endl;
names.push_back(var);
pos=pos1+1;
}
if (pos < lString.size()){
string var(lString.substr(pos,lString.size()));
deleteSpace(var);
neolog << "var:"<< var << endl;
names.push_back(var);
}
}
}
ShaderParam::SHADERPARAMTYPE eType;
if (attrib_type == "sampler1D" || attrib_type == "sampler1DShadow" ){
eType=ShaderParam::GLSL_SMP1;
}else
if (attrib_type == "sampler2D" || attrib_type == "sampler2DShadow"){
eType=ShaderParam::GLSL_SMP2;
}else
if (attrib_type == "sampler3D" || attrib_type == "sampler3DShadow"){
eType=ShaderParam::GLSL_SMP3;
}else
if (attrib_type == "samplerCube"){
eType=ShaderParam::GLSL_SMPC;
}else
if (attrib_type == "int"){
eType=ShaderParam::GLSL_INT;
}else
if (attrib_type == "ivec2"){
eType=ShaderParam::GLSL_INT2;
}else
if (attrib_type == "ivec3"){
eType=ShaderParam::GLSL_INT3;
}else
if (attrib_type == "ivec4"){
eType=ShaderParam::GLSL_INT4;
}else
if (attrib_type == "float"){
eType=ShaderParam::GLSL_FLOAT;
}else
if (attrib_type == "vec2"){
eType=ShaderParam::GLSL_FLOAT2;
}else
if (attrib_type == "vec3"){
eType=ShaderParam::GLSL_FLOAT3;
}else
if (attrib_type == "vec4"){
eType=ShaderParam::GLSL_FLOAT4;
}else
if (attrib_type == "mat2"){
eType=ShaderParam::GLSL_MAT2;
}else
if (attrib_type == "mat3"){
eType=ShaderParam::GLSL_MAT3;
}else
if (attrib_type == "mat4"){
eType=ShaderParam::GLSL_MAT4;
}
vector<string>::iterator iter=names.begin();
while (iter != names.end()){
GLSLattrib Param;
if( *iter == "Tangent"){
Param.m_uiIndex = 14;
}else
if( *iter == "Binormal"){
Param.m_uiIndex = 15;
}else
Param.m_eType = eType;
Param.m_strName = *iter;
m_vAttrib.push_back( Param );
iter++;
}
return true;
}
bool ProgramGLSL::match_uniform(const string& inString){
string lString=inString;
string::size_type pos=0;
string::size_type pos1=0;
string::size_type pos2=0;
string uniform_type;
vector<string> names;
pos=0;
// delete the "uniform" word
if ( ( pos = lString.find(" ",pos)) != string::npos ){
lString.erase(0,pos+1);
// cut the type of the uniform(s)
pos=0;
pos1=pos;
if ( ( pos1 = lString.find(" ",pos1)) != string::npos ){
uniform_type=lString.substr(pos,pos1-pos);
deleteSpace(uniform_type);
lString.erase(pos,pos1-pos);
neolog << "Type:"<< uniform_type << endl;
pos=0;
while ( ( pos1 = lString.find(",",pos)) != string::npos ){
string var=lString.substr(pos,pos1-pos);
deleteSpace(var);
neolog << "var:"<<var << endl;
names.push_back(var);
pos=pos1+1;
}
if (pos < lString.size()){
string var(lString.substr(pos,lString.size()));
deleteSpace(var);
neolog << "var:"<< var << endl;
names.push_back(var);
}
}
}
ShaderParam::SHADERPARAMTYPE eType;
if (uniform_type == "sampler1D" || uniform_type == "sampler1DShadow"){
eType=ShaderParam::GLSL_SMP1;
}else
if (uniform_type == "sampler2D" || uniform_type == "sampler2DShadow"){
eType=ShaderParam::GLSL_SMP2;
}else
if (uniform_type == "sampler3D" || uniform_type == "sampler3DShadow"){
eType=ShaderParam::GLSL_SMP3;
}else
if (uniform_type == "samplerCube"){
eType=ShaderParam::GLSL_SMPC;
}else
if (uniform_type == "int"){
eType=ShaderParam::GLSL_INT;
}else
if (uniform_type == "ivec2"){
eType=ShaderParam::GLSL_INT2;
}else
if (uniform_type == "ivec3"){
eType=ShaderParam::GLSL_INT3;
}else
if (uniform_type == "ivec4"){
eType=ShaderParam::GLSL_INT4;
}else
if (uniform_type == "float"){
eType=ShaderParam::GLSL_FLOAT;
}else
if (uniform_type == "vec2"){
eType=ShaderParam::GLSL_FLOAT2;
}else
if (uniform_type == "vec3"){
eType=ShaderParam::GLSL_FLOAT3;
}else
if (uniform_type == "vec4"){
eType=ShaderParam::GLSL_FLOAT4;
}else
if (uniform_type == "mat2"){
eType=ShaderParam::GLSL_MAT2;
}else
if (uniform_type == "mat3"){
eType=ShaderParam::GLSL_MAT3;
}else
if (uniform_type == "mat4"){
eType=ShaderParam::GLSL_MAT4;
}
vector<string>::iterator iter=names.begin();
while (iter != names.end()){
ShaderParam *pkParam = new ShaderParam;
pkParam->m_eType = eType;
pkParam->m_sName = *iter;
m_kParams.Insert( *iter, pkParam );
m_vpkParams.push_back( pkParam );
iter++;
}
return true;
}
bool ProgramGLSL::CompileVert( const string *pstrSource )
{
GLint vertCompiled;
GLhandleARB handleVS;
m_bIsCompiled = false;
if( pstrSource ){
m_strSource = *pstrSource;
}
neolog << "Parsing Vertex Shader: "<< this->GetName() <<endl;
BindParamGLSL(m_strSource);
const GLcharARB *sourceV=new GLcharARB[m_strSource.size()+2];
GLcharARB *p=(GLcharARB *)sourceV;
// parse the source code
string::iterator iter=m_strSource.begin();
while (iter != m_strSource.end() ){
*(p++)=*(iter++);
}
*p='\0';*(++p)='\0';
handleVS = neoglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
neoglShaderSourceARB(handleVS,1,&sourceV,NULL);
neoglCompileShaderARB(handleVS);
neoglGetObjectParameterivARB(handleVS,
GL_OBJECT_COMPILE_STATUS_ARB, &vertCompiled);
pprintInfoLog(handleVS);
delete[] sourceV;
if (vertCompiled){
m_vhVS.push_back(handleVS);
m_bIsCompiled = true;
return true;
}
return false;
}
bool ProgramGLSL::CompileFrag( const string *pstrSource )
{
GLint fragCompiled;
GLhandleARB handleFS;
m_bIsCompiled = false;
if( pstrSource ){
m_strSource = *pstrSource;
}
neolog <<"Parsing Fragment Shader: "<< this->GetName() <<endl;
BindParamGLSL(m_strSource);
const GLcharARB *sourceF=new GLcharARB[m_strSource.size()+2];
GLcharARB *p=(GLcharARB *)sourceF;
// parse the source code
string::iterator iter=m_strSource.begin();
while (iter != m_strSource.end() ){
*(p++)=*(iter++);
}
*p='\0';*(++p)='\0';
handleFS = neoglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
neoglShaderSourceARB(handleFS,1,&sourceF,NULL);
neoglCompileShaderARB(handleFS);
neoglGetObjectParameterivARB(handleFS,
GL_OBJECT_COMPILE_STATUS_ARB, &fragCompiled);
pprintInfoLog(handleFS);
delete[] sourceF;
if (fragCompiled){
m_vhFS.push_back(handleFS);
m_bIsCompiled = true;
return true;
}
return false;
}
bool ProgramGLSL::CompileGeometry( const string *pstrSource )
{
GLint geomCompiled;
GLhandleARB handleGS;
m_bIsCompiled = false;
if ( !this->m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_GEOMETRY_SHADER ) ){
return false;
}
if( pstrSource ){
m_strSource = *pstrSource;
}
neolog <<"Parsing Geometry Shader: "<< this->GetName() <<endl;
BindParamGLSL(m_strSource);
const GLcharARB *sourceG=new GLcharARB[m_strSource.size()+2];
GLcharARB *p=(GLcharARB *)sourceG;
// parse the source code
string::iterator iter=m_strSource.begin();
while (iter != m_strSource.end() ){
*(p++)=*(iter++);
}
*p='\0';*(++p)='\0';
handleGS = neoglCreateShaderObjectARB(GL_GEOMETRY_SHADER_EXT);
neoglShaderSourceARB(handleGS,1,&sourceG,NULL);
neoglCompileShaderARB(handleGS);
neoglGetObjectParameterivARB(handleGS,
GL_OBJECT_COMPILE_STATUS_ARB, &geomCompiled);
pprintInfoLog(handleGS);
delete[] sourceG;
if (geomCompiled){
m_vhGS.push_back(handleGS);
m_bIsCompiled = true;
return true;
}
return false;
}
bool ProgramGLSL::Link( void )
{
GLint linked;
m_hProgram = neoglCreateProgramObjectARB();
// link all the Vertex Shaders
vector<GLhandleARB>::iterator iter=m_vhVS.begin();
vector<GLhandleARB>::iterator end=m_vhVS.end();
while( iter != end){
neoglAttachObjectARB(m_hProgram, *iter);
neoglDeleteObjectARB(*iter);
iter++;
}
// link all the Fragment Shaders
iter=m_vhFS.begin();
end=m_vhFS.end();
while( iter != end){
neoglAttachObjectARB(m_hProgram, *iter);
neoglDeleteObjectARB(*iter);
iter++;
}
if (m_vhGS.size() > 0){
if ( m_iGeometryOutVertex == 0 ){
GLint n;
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
neoglProgramParameteriEXT(m_hProgram, GL_GEOMETRY_VERTICES_OUT_EXT, n);
}else{
neoglProgramParameteriEXT(m_hProgram, GL_GEOMETRY_VERTICES_OUT_EXT, m_iGeometryOutVertex);
}
}
// link all the Geometry Shaders
iter=m_vhGS.begin();
end=m_vhGS.end();
while( iter != end){
neoglAttachObjectARB(m_hProgram, *iter);
neoglDeleteObjectARB(*iter);
iter++;
}
if (m_vhGS.size() > 0){
neoglProgramParameteriEXT(m_hProgram,GL_GEOMETRY_INPUT_TYPE_EXT ,m_eGeometryInpType );
neoglProgramParameteriEXT(m_hProgram,GL_GEOMETRY_OUTPUT_TYPE_EXT ,m_eGeometryOutType );
//neoglProgramParameteriEXT(m_hProgram,GL_GEOMETRY_INPUT_TYPE_EXT ,GL_TRIANGLES);
//neoglProgramParameteriEXT(m_hProgram,GL_GEOMETRY_OUTPUT_TYPE_EXT ,GL_TRIANGLE_STRIP);
}
// bind all the attributes
vector<GLSLattrib>::iterator attrIter=m_vAttrib.begin();
vector<GLSLattrib>::iterator attrEnd=m_vAttrib.end();
while( attrIter != attrEnd){
neoglBindAttribLocationARB(m_hProgram,attrIter->m_uiIndex,attrIter->m_strName.c_str());
attrIter++;
}
neoglLinkProgramARB(m_hProgram);
neoglGetObjectParameterivARB(m_hProgram,
GL_OBJECT_LINK_STATUS_ARB, &linked);
pprintInfoLog(m_hProgram);
if (linked ){
m_bIsCompiled = true;
return true;
}
return false;
}
bool ProgramGLSL::Clear( void )
{
ClearParams();
m_strSource.clear();
if( m_hProgram )
fpneoglDeleteObjectARB(m_hProgram);
m_hProgram=0;
return true;
}
bool ProgramGLSL::Compile( const string *pstrSource )
{
if( m_bIsCompiled && !pstrSource )
return true;
ClearParams();
if( pstrSource )
m_strSource = *pstrSource;
BindParamGLSL(m_strSource);
if( m_hProgram )
fpneoglDeleteObjectARB(m_hProgram);
// ignore the vertex shader
if ( m_eType == NEPT_GL_GLSLV ){
m_bIsCompiled = true;
return true;
}else if ( m_eType == NEPT_GL_GLSLF ){
neolog << "General compile Parsing Shader: "<< this->GetName() <<endl;
GLint linked,vertCompiled,fragCompiled;
const GLcharARB *sourceV=new GLcharARB[m_strSource.size()+2];
const GLcharARB *sourceF=new GLcharARB[m_strSource.size()+2];
GLcharARB *p=(GLcharARB *)sourceV;
GLcharARB *q=(GLcharARB *)sourceF;
// parse the source code
// spliting vertex form fragment shader by the couple of char "##"
string::iterator iter=m_strSource.begin();
while (iter != m_strSource.end() && !(*iter=='#' && *(iter+1)=='#')){
*(p++)=*(iter++);
}
if (iter != m_strSource.end()){
iter++;
iter++;
while ( iter != m_strSource.end() ){
*(q++)=*(iter++);
}
}
*p='\0';*(++p)='\0';
*q='\0';*(++q)='\0';
m_vhFS[0] = neoglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
neoglShaderSourceARB(m_vhFS[0],1,&sourceF,NULL);
neoglCompileShaderARB(m_vhFS[0]);
neoglGetObjectParameterivARB(m_vhFS[0],
GL_OBJECT_COMPILE_STATUS_ARB, &fragCompiled);
// pprintInfoLog(m_vhFS);
m_vhVS[0] = neoglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
neoglShaderSourceARB(m_vhVS[0],1,&sourceV,NULL);
neoglCompileShaderARB(m_vhVS[0]);
neoglGetObjectParameterivARB(m_vhVS[0],
GL_OBJECT_COMPILE_STATUS_ARB, &vertCompiled);
// pprintInfoLog(m_vhVS);
m_hProgram = neoglCreateProgramObjectARB();
neoglAttachObjectARB(m_hProgram, m_vhVS[0]);
neoglAttachObjectARB(m_hProgram, m_vhFS[0]);
// Link the program object and print out the info log
neoglDeleteObjectARB(m_vhVS[0]);
neoglDeleteObjectARB(m_vhFS[0]);
neoglLinkProgramARB(m_hProgram);
neoglGetObjectParameterivARB(m_hProgram,
GL_OBJECT_LINK_STATUS_ARB, &linked);
pprintInfoLog(m_hProgram);
delete[] sourceF;
delete[] sourceV;
if (linked ){
m_bIsCompiled = true;
return true;
}
}
return false;
}
bool ProgramGLSL::Bind( RenderPrimitive *pkPrimitive )
{
#ifdef _DEBUG
if( !m_bIsCompiled )
{
neolog << LogLevel( ERROR ) << "*** Unable to bind " << ( ( m_eShaderType == VERTEXSHADER ) ? "vertex" : "fragment" ) << " program: Program not compiled" << endl;
return false;
}
#endif
// glEnable( m_eType );
/* if( neoglCheckError( string( "*** Unable to bind " ) + ( ( m_eShaderType == VERTEXSHADER ) ? "vertex" : "fragment" ) + " program: " ) )
{
GLint iErrorPos;
glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &iErrorPos );
const GLubyte *pucError;
pucError = glGetString( GL_PROGRAM_ERROR_STRING_ARB );
neolog << LogLevel( ERROR )
<< " Position: " << iErrorPos << endl
<< " Error: " << pucError << endl;
Unbind();
return false;
}
*/
//Bind all params
// Set up initial uniform values
neoglUseProgramObjectARB(m_hProgram);
vector< ShaderParam* >::iterator ppkParam = m_vpkParams.begin();
vector< ShaderParam* >::iterator ppkEnd = m_vpkParams.end();
for( ; ppkParam != ppkEnd; ++ppkParam ){
BindParameterGLSLP( m_pkDevice, m_eType, *ppkParam, pkPrimitive, m_hProgram);
}
//We don't use updated params for now, clear to avoid stockpiling pointers
m_vpkUpdatedParams.clear();
// neoglCheckError( "*** Error binding parameters: " );
return true;
}
bool ProgramGLSL::Unbind()
{
//glDisable( m_eType );
neoglUseProgramObjectARB(NULL);
return true;
}
bool ProgramGLSL::BindLightParams( RenderPrimitive *pkPrimitive )
{
//Bind all params
vector< ShaderParam* >::iterator ppkParam = m_vpkParams.begin();
vector< ShaderParam* >::iterator ppkEnd = m_vpkParams.end();
for( ; ppkParam != ppkEnd; ++ppkParam )
{
if( ( (*ppkParam)->m_eType == ShaderParam::PPT_SYSTEM ) && ( (*ppkParam)->m_Value.m_eSystemID & ShaderParam::LIGHTPARAM ) )
BindParameterGLSLP( m_pkDevice, m_eType, *ppkParam, pkPrimitive , m_hProgram);
}
return true;
}
};
See more files for this project here