00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <state/shader.h>
00025 #include <texture/multiTex.h>
00026 #include <iostream>
00027 #include <GL/glUtil.h>
00028
00029 using namespace std;
00030 using namespace gutz;
00031
00032 using namespace glift;
00033
00034
00035
00036
00037
00038 Shader::Shader( GenState* genState )
00039 {
00040 initMembers( NULL, NULL, genState ? VecStateP(1,genState) : VecStateP() );
00041 }
00042
00043 Shader::Shader( const VecStateP& genAttribs )
00044 {
00045 initMembers( NULL, NULL, genAttribs );
00046 }
00047
00048 Shader::Shader( Texture* tex, GenState* genState )
00049 {
00050 initMembers( tex, NULL, genState ? VecStateP(1,genState) : VecStateP() );
00051 }
00052
00053 Shader::Shader( Texture* tex, const VecStateP& genAttribs )
00054 {
00055 initMembers( tex, NULL, genAttribs);
00056 }
00057
00058 Shader::Shader( Texture* tex, ProgShader* progShader, GenState* genState )
00059 {
00060 initMembers( tex, progShader, genState ? VecStateP(1,genState) : VecStateP() );
00061 }
00062
00063 Shader::Shader( Texture* tex, ProgShader* progShader, const VecStateP& genAttribs )
00064 {
00065 initMembers( tex, progShader, genAttribs );
00066 }
00067
00068 Shader::Shader( const Shader& rhs )
00069 {
00070 initMembers( rhs );
00071 }
00072
00073 Shader& Shader::operator=( const Shader& rhs )
00074 {
00075 if( &rhs != this ) {
00076 initMembers( rhs );
00077 }
00078 return *this;
00079 }
00080
00081 void Shader::initMembers( Texture* tex, ProgShader* progShader, const VecStateP& genAttribs )
00082 {
00083 m_texture = tex;
00084 m_progShader = progShader;
00085 m_genAttribs = genAttribs;
00086
00087
00088 if( m_progShader || m_texture) {
00089 checkTexture();
00090 }
00091 }
00092
00093 void Shader::initMembers( const Shader& rhs )
00094 {
00095 initMembers( rhs.m_texture, rhs.m_progShader, rhs.m_genAttribs );
00096 }
00097
00098 void Shader::checkTexture()
00099 {
00100
00101 if( m_progShader && m_texture ) {
00102 if( m_texture->numTexUnits() != m_progShader->numTexUnits() ) {
00103 err() << "initMembers(...) Error:\n"
00104 << "\tShader defines " << m_progShader->numTexUnits()
00105 << "\ttexture perturbation(s) but " << m_texture->numTexUnits() << " textures were provided.\n"
00106 << "\t'EmptyTexture' objects can be used to enable texture\n"
00107 << "\tunits for their texture coordinates only.\n";
00108 exit(1);
00109 }
00110 }
00111
00112
00113 MultiTex* multiTex = dynamic_cast<MultiTex*>( m_texture );
00114 if( m_progShader && !multiTex ) {
00115 if( m_progShader->numTexUnits() > 1 ) {
00116 err() << "initMembers(...) Error:\n"
00117 << "\tShader requires " << m_progShader->numTexUnits()
00118 << "\ttexture unit(s) and only 1 texture was provided.\n"
00119 << "\t'EmptyTexture' objects can be used to enable texture\n"
00120 << "\tunits for their texture coordinates only.\n";
00121 exit(1);
00122 }
00123 }
00124 }
00125
00126 Shader::~Shader()
00127 {}
00128
00129
00130
00131 MultiTexCoord* Shader::genTexCoords( const arrayw2f& rawTexCoord, const vec3f& primScale ) const
00132 {
00133 if( m_texture && rawTexCoord.size()==0 ) {
00134 err() << "genTexCoords(...) Error:\n"
00135 << "\tAttempt to create texture coordinates for a primitive that does\n"
00136 << "\tNOT have texture coordinates enabled.\n"
00137 << "\tIf texture coordinates are desired, construct primitive with \n"
00138 << "\ttexture coordinate generation enabled.\n";
00139 exit(1);
00140 }
00141
00142 MultiTexCoord* multiTexCoord = NULL;
00143 if( m_progShader == NULL ) {
00144 if( !rawTexCoord.empty() ) {
00145 multiTexCoord = new MultiTexCoord( this->numTexUnits(), rawTexCoord );
00146 }
00147 }
00148 else {
00149
00150
00151 multiTexCoord = m_progShader->genTexCoords( rawTexCoord, primScale );
00152 }
00153
00154
00155 if( MultiTex* tex = dynamic_cast<MultiTex*>(m_texture) ) {
00156 for(int t=0; t < numTexUnits(); t++) {
00157 if( SubTex* subtex = dynamic_cast<SubTex*>((*tex)[t]) ) {
00158 subtex->adjustTexCoord( (*multiTexCoord)[t] );
00159 }
00160 }
00161 }
00162 else if( m_texture ) {
00163 if( SubTex* subtex = dynamic_cast<SubTex*>(m_texture) ) {
00164 subtex->adjustTexCoord( (*multiTexCoord)[0] );
00165 }
00166 }
00167
00168 return multiTexCoord;
00169 }
00170
00171 void Shader::bindDef()
00172 {
00173 if( m_texture ) { m_texture->bind(); }
00174 if( m_progShader ) { m_progShader->bind(); }
00175
00176 for(unsigned int i=0; i < m_genAttribs.size(); i++) {
00177 if( m_genAttribs[i] ) { m_genAttribs[i]->bind(); }
00178 }
00179 glErr(estr(),"Shader", "bindDef");
00180 }
00181
00182 void Shader::releaseDef()
00183 {
00184 for(int i=m_genAttribs.size()-1; i >= 0; i--) {
00185 if( m_genAttribs[i] ) { m_genAttribs[i]->release(); }
00186 }
00187 if( m_progShader ) { m_progShader->release(); }
00188 if( m_texture ) { m_texture->release(); }
00189 }
00190
00191