10 #include <boost/algorithm/string/predicate.hpp>
12 using boost::algorithm::icontains;
16 #define snprintf _snprintf
19 typedef std::pair< unsigned int , std::pair< std::string, std::string > >
ProgramCacheKey;
26 static ProgramCache::key_type
cacheKey(
const std::string &vp,
const std::string &fp,
const char *defines )
28 unsigned int defhash = 0;
29 if (defines != NULL) {
32 defhash ^= (defhash * 127) | *(defines++);
34 return std::pair< unsigned int , std::pair< std::string, std::string > > (defhash, std::pair< std::string, std::string > ( vp, fp ));
38 bool allowSoftwareEmulation =
false )
41 const GLsizei LOGBUF = 1024;
42 GLsizei infologLength = 0;
43 char infoLog[LOGBUF+1];
50 if (infologLength > 0) {
52 assert(infologLength <= LOGBUF);
53 infoLog[infologLength] = 0;
56 if (!allowSoftwareEmulation) {
57 if (icontains(infoLog,
"run in software"))
59 if (icontains(infoLog,
"run on software"))
70 const GLsizei LOGBUF = 1024;
71 GLsizei infologLength = 0;
72 char infoLog[LOGBUF+1];
80 assert(infologLength <= LOGBUF);
81 infoLog[infologLength] = 0;
83 if (infologLength > 0)
84 fprintf( stderr,
"%s\n", infoLog );
89 std::string dirname = path.substr(0,path.find_last_of(
'/'));
94 const char *include_directive =
"#include \"";
95 const size_t include_directive_len = 10;
99 processed_includes.insert(path);
103 if (strncmp(buf, include_directive, include_directive_len) == 0) {
105 char *eos = strchr(buf+include_directive_len,
'\"');
108 std::string includepath = dirname +
"/" + std::string(buf+include_directive_len);
109 if (processed_includes.count(includepath) == 0) {
111 lines.push_back(
"#line 0\n");
120 lines.push_back(
"\n");
121 snprintf(buf, buflen,
"#line %lu\n", lineno);
122 lines.push_back(buf);
126 lines.push_back(
"\n");
130 path.c_str(), lineno);
134 lines.push_back(buf);
147 std::set<std::string> processed_includes;
148 std::vector<std::string> lines;
157 for (std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
158 sourcelen += it->length();
159 source.reserve(sourcelen);
160 for (std::vector<std::string>::const_iterator it = lines.begin(); it != lines.end(); ++it)
166 static std::string
appendDefines(
const std::string &prog,
const char *extra_defines )
168 std::string::size_type nlpos = prog.find_first_of(
'\n');
170 if (nlpos == std::string::npos)
173 std::string firstline = prog.substr(0, nlpos);
175 if (firstline.find(
"#version") != std::string::npos)
177 +
"\n" + std::string(extra_defines)
179 + prog.substr(nlpos);
181 return std::string(extra_defines)
188 if (vprogram[0] ==
'\0' && fprogram[0] ==
'\0')
return 0;
194 #ifdef OSX_LOWER_THAN_10_4
199 while ( ( errCode = glGetError() ) != GL_NO_ERROR )
200 printf(
"Error code %s\n", gluErrorString( errCode ) );
202 std::string vpfilename = std::string(
"programs/") + vprogram +
".vp";
203 std::string fpfilename = std::string(
"programs/") + fprogram +
".fp";
205 std::string vertexprg, fragprg;
208 if ( (vperr >
Ok) || (fperr >
Ok) ) {
210 fprintf( stderr,
"Vertex Program Error: Failed to open file %s\n", vpfilename.c_str() );
212 fprintf( stderr,
"Fragment Program Error: Failed to open file %s\n", fpfilename.c_str() );
216 if (extra_defines != NULL) {
221 GLint vproghandle = 0;
222 GLint fproghandle = 0;
226 const char *tmp = vertexprg.c_str();
233 fprintf( stderr,
"Vertex Program Error: Failed to compile %s\n", vprogram );
238 fprintf( stderr,
"Vertex Program Error: Failed log validation for %s. Inspect log above for details.\n", vprogram );
246 const char *tmp = fragprg.c_str();
253 fprintf( stderr,
"Fragment Program Error: Failed to compile %s\n", fprogram );
259 fprintf( stderr,
"Vertex Program Error: Failed log validation for %s. Inspect log above for details.\n", vprogram );
276 fprintf( stderr,
"Shader Program Error: Failed to link %s to %s\n", vprogram, fprogram );
280 fprintf( stderr,
"Shader Program Error: Failed log validation for vp:%s fp:%s. Inspect log above for details.\n", vprogram, fprogram );
295 while ( ( errCode = glGetError() ) != GL_NO_ERROR ) {
296 printf(
"Error code %s\n", gluErrorString( errCode ) );
302 int GFXCreateProgram(
const char *vprogram,
const char *fprogram,
const char *extra_defines )
304 ProgramCache::key_type key =
cacheKey( vprogram, fprogram, extra_defines );
305 ProgramCache::const_iterator it =
programCache.find( key );
315 return GFXCreateProgram( (
const char*) vprogram, (
const char*) fprogram, (
const char*) extra_defines );
351 static bool initted =
false;
409 #define NUMFRAMESLOOK 128
417 double framerate = 1./(thistime-
lasttime);
418 static double toofast = 80;
419 static double tooslow = 29;
420 static unsigned lim = 10;
421 static int penalty = 10;
422 static float lowratio = .125;
423 static float highratio = .75;
425 if (framerate > toofast) curframe =
TOOFAST;
426 else if (framerate > tooslow)
443 incorrect += penalty;
445 double myratio = (double) correct/(
double) (correct+incorrect);
446 if (curframe ==
TOOFAST && myratio > highratio) {
447 static int toomanyswitches = 3;
448 toomanyswitches -= 1;
449 if (toomanyswitches >= 0)
451 }
else if (myratio > lowratio) {
466 static bool framerate_changes_shader =
468 if (framerate_changes_shader) {
506 static int lastprogram = 0;
507 if (program != lastprogram)
509 if (program != lastprogram
515 lastprogram = program;
516 }
else {
return 0; }
return program;
522 int curprogram = defaultprogram;