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 #include <state/vertexProgARB.h>
00026 #include <string.h>
00027 #include <iostream>
00028
00029 using namespace std;
00030 using namespace glift;
00031 using namespace gutz;
00032
00033
00034
00035
00036 VertexProgARB::VertexProgARB( const char *vertProg, bool isFileName, PBuffGlift* pbuff, bool noload)
00037 : m_vertProg(0), m_vertProgFile(0), m_shaderNum(0), m_pbuff(0)
00038 {
00039 initMembers( vertProg, isFileName, 0, pbuff );
00040 if(!noload)
00041 this->init();
00042 }
00043
00044
00045
00046
00047 VertexProgARB::VertexProgARB( const VertexProgARB &rhs)
00048 {
00049 initMembers(rhs);
00050 }
00051
00052
00053
00054
00055 VertexProgARB& VertexProgARB::operator=( const VertexProgARB& rhs )
00056 {
00057 initMembers(rhs);
00058 return *this;
00059 }
00060
00061
00062
00063
00064 void VertexProgARB::initMembers( const char *vertProg, bool isFileName, GLuint shaderNum, PBuffGlift* pbuff )
00065 {
00066 if(!glew.ARB_vertex_program)
00067 {
00068 err() << "initMembers() Error:\n"
00069 << "\tGL_ARB_fragment_program is not available.\n"
00070 << "\tVertexProgARB only available if using a graphics card that supports it.\n";
00071 exit(1);
00072 }
00073
00074 if(isFileName)
00075 {
00076 if(m_vertProgFile) delete [] m_vertProgFile;
00077 m_vertProgFile = new char[strlen(vertProg)+1];
00078 assert(m_vertProgFile);
00079 strcpy(m_vertProgFile, vertProg);
00080
00081 FILE *fp;
00082 long length;
00083
00084 if (!(fp = fopen(m_vertProgFile,"rb")))
00085 {
00086 err() << "initMembers() error: " << vertProg << " could not be read " << endl;
00087 return;
00088 }
00089
00090 fseek(fp, 0, SEEK_END);
00091 length = ftell(fp);
00092 assert(length >= 1 );
00093 fseek(fp, 0, SEEK_SET);
00094
00095 if( m_vertProg ) {delete [] m_vertProg;}
00096 m_vertProg = new char[length+1];
00097 assert(m_vertProg);
00098
00099 fread( m_vertProg, 1, length, fp);
00100 m_vertProg[length] = '\0';
00101 }
00102 else
00103 {
00104 if(m_vertProgFile) delete [] m_vertProgFile;
00105 m_vertProg = new char[strlen(vertProg)+1];
00106 assert(m_vertProg);
00107 strcpy( m_vertProg, vertProg );
00108 }
00109
00110 m_shaderNum = shaderNum;
00111 m_pbuff = pbuff;
00112 glGetProgramivARB( GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &m_maxLocalParams );
00113 }
00114
00115
00116
00117
00118 void VertexProgARB::initMembers( const VertexProgARB &rhs)
00119 {
00120 if(rhs.m_vertProg)
00121 {
00122 m_vertProg = new char[strlen(rhs.m_vertProg)];
00123 }
00124 if(rhs.m_vertProgFile)
00125 {
00126 m_vertProgFile = new char[strlen(rhs.m_vertProgFile)];
00127 }
00128
00129 m_shaderNum = rhs.m_shaderNum;
00130 m_pbuff = rhs.m_pbuff;
00131 m_maxLocalParams = rhs.m_maxLocalParams;
00132 }
00133
00134
00135
00136
00137 VertexProgARB::~VertexProgARB()
00138 {
00139 destroy();
00140 if(m_vertProg) delete [] m_vertProg;
00141 m_vertProg = 0;
00142 if(m_vertProgFile) delete [] m_vertProgFile;
00143 m_vertProgFile = 0;
00144 }
00145
00146
00147
00148
00149 void VertexProgARB::destroy()
00150 {
00151 if( m_pbuff ) {
00152 m_pbuff->enable(true);
00153 }
00154
00155 if(glew.ARB_vertex_program)
00156 {
00157 glDeleteProgramsARB(1, &m_shaderNum );
00158 }
00159
00160 if( m_pbuff ) {
00161 m_pbuff->disable();
00162 }
00163 }
00164
00165
00166
00167
00168 void VertexProgARB::init()
00169 {
00170
00171 if( m_pbuff ) {
00172 m_pbuff->enable(true);
00173 }
00174
00175 if(glew.ARB_vertex_program && m_vertProg)
00176 {
00177 glGenProgramsARB( 1, &m_shaderNum);
00178
00179 this->bindDef();
00180
00181 #ifdef NDEBUG // Running in optimized mode, so need to eat unrelated GL errors
00182 glGetError();
00183 #endif
00184
00185 glProgramStringARB( GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(m_vertProg), m_vertProg);
00186
00187 if (glGetError() != 0)
00188 {
00189 int position;
00190 glGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &position);
00191 err() << "init() error: " << glGetString(GL_PROGRAM_ERROR_STRING_ARB) << " at character " << position << endl;
00192 estr() << m_vertProg << endl;
00193 }
00194
00195 this->releaseDef();
00196 }
00197
00198 if( m_pbuff ) {
00199 m_pbuff->disable();
00200 }
00201 }
00202
00203
00204
00205
00206 void VertexProgARB::reset()
00207 {
00208 destroy();
00209 init();
00210
00211 if( isCompiled() ) {
00212 compile();
00213 }
00214 }
00215
00216
00217
00218
00219 void VertexProgARB::reload(const char *shader)
00220 {
00221 if(!shader)
00222 {
00223 err() << "reload(), null shader" << endl;
00224 return;
00225 }
00226
00227 if(m_vertProg) {delete [] m_vertProg;}
00228 m_vertProg = 0;
00229
00230 m_vertProg = new char[strlen(shader)+1];
00231 assert(m_vertProg);
00232 m_vertProg[strlen(shader)] = '\0';
00233 strcpy(m_vertProg, shader);
00234
00235
00236 init();
00237 }
00238
00239
00240
00241
00242 void VertexProgARB::setLocalConstf(unsigned int constNum, const vec4f& constant)
00243 {
00244 assert( constNum < (uint)m_maxLocalParams );
00245
00246
00247
00248 bindDef();
00249 glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, constNum, constant.v());
00250
00251
00252
00253
00254
00255
00256 releaseDef();
00257
00258 }
00259
00260 void VertexProgARB::setLocalConstd(unsigned int constNum, const vec4d& constant)
00261 {
00262 assert( constNum < (uint)m_maxLocalParams );
00263
00264
00265
00266 bindDef();
00267 glProgramLocalParameter4dvARB(GL_VERTEX_PROGRAM_ARB, constNum, constant.v());
00268 releaseDef();
00269
00270 }
00271
00272
00273
00274
00275 void VertexProgARB::bindDef()
00276 {
00277 glEnable( GL_VERTEX_PROGRAM_ARB );
00278 glBindProgramARB( GL_VERTEX_PROGRAM_ARB, m_shaderNum);
00279
00280 }
00281
00282
00283
00284
00285 void VertexProgARB::releaseDef()
00286 {
00287 glDisable( GL_VERTEX_PROGRAM_ARB);
00288
00289 }
00290
00291
00292
00293
00294 void VertexProgARB::setProgFile(const char *name)
00295 {
00296 if(m_vertProgFile) delete[] m_vertProgFile;
00297 m_vertProgFile = 0;
00298 if(name)
00299 {
00300 m_vertProgFile = new char[strlen(name)+1];
00301 strcpy(m_vertProgFile,name);
00302 m_vertProgFile[strlen(name)] = '\0';
00303 }
00304 }
00305