31 #include <dispatch/dispatch.h>
33 #include <CoreFoundation/CoreFoundation.h>
34 #include <IOSurface/IOSurface.h>
36 #include <OpenGL/CGLIOSurface.h>
37 #include <OpenGL/CGLMacro.h>
38 #include <ApplicationServices/ApplicationServices.h>
41 static map<VuoGlPoolType, map<unsigned long, vector<GLuint> > > VuoGlPool
__attribute__((init_priority(101)));
60 if (VuoGlPool[type][size].size())
62 name = VuoGlPool[type][size].back();
63 VuoGlPool[type][size].pop_back();
68 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
70 if (type == VuoGlPool_ArrayBuffer || type == VuoGlPool_ElementArrayBuffer)
72 glGenBuffers(1, &name);
73 GLenum bufferType = type == VuoGlPool_ArrayBuffer ? GL_ARRAY_BUFFER : GL_ELEMENT_ARRAY_BUFFER;
74 glBindBuffer(bufferType, name);
75 glBufferData(bufferType, size, NULL, GL_STREAM_DRAW);
76 glBindBuffer(bufferType, 0);
81 VUserLog(
"Unknown pool type %d.", type);
101 if (type == VuoGlPool_ArrayBuffer || type == VuoGlPool_ElementArrayBuffer)
102 VuoGlPool[type][size].push_back(name);
104 VUserLog(
"Unknown pool type %d.", type);
112 static void __attribute__((constructor)) VuoGlPool_referenceCountsInit(
void)
120 void VuoGlPool_retainF(GLuint glBufferName,
const char *file,
unsigned int linenumber,
const char *func)
122 if (glBufferName == 0)
127 VuoGlPoolReferenceCounts::iterator it = VuoGlPool_referenceCounts.find(glBufferName);
128 if (it == VuoGlPool_referenceCounts.end())
129 VuoGlPool_referenceCounts[glBufferName] = 1;
131 ++VuoGlPool_referenceCounts[glBufferName];
142 if (glBufferName == 0)
147 VuoGlPoolReferenceCounts::iterator it = VuoGlPool_referenceCounts.find(glBufferName);
148 if (it == VuoGlPool_referenceCounts.end())
149 VuoLog(file, linenumber, func,
"Error: VuoGlPool_release() was called with OpenGL Buffer Object %d, which was never retained.", glBufferName);
152 if (--VuoGlPool_referenceCounts[glBufferName] == 0)
180 internalFormat(internalFormat),
221 if (format == GL_YCBCR_422_APPLE)
222 return GL_UNSIGNED_SHORT_8_8_APPLE;
223 else if (format == GL_RGB
224 || format == GL_LUMINANCE
225 || format == GL_LUMINANCE_ALPHA
226 || format == GL_BGR_EXT)
227 return GL_UNSIGNED_BYTE;
228 else if (format == GL_RGBA
229 || format == GL_RGBA8
230 || format == GL_BGRA)
231 return GL_UNSIGNED_INT_8_8_8_8_REV;
232 else if (format == GL_DEPTH_COMPONENT)
235 return GL_UNSIGNED_BYTE;
238 VUserLog(
"Unknown format %s", formatString);
249 if (format == GL_LUMINANCE
250 || format == GL_LUMINANCE8
251 || format == GL_LUMINANCE16F_ARB
252 || format == GL_LUMINANCE32F_ARB
253 || format == GL_DEPTH_COMPONENT)
255 else if (format == GL_YCBCR_422_APPLE
256 || format == GL_LUMINANCE_ALPHA
257 || format == GL_LUMINANCE_ALPHA16F_ARB
258 || format == GL_LUMINANCE_ALPHA32F_ARB)
260 else if (format == GL_RGB
261 || format == GL_RGB16F_ARB
262 || format == GL_RGB32F_ARB
263 || format == GL_BGR_EXT)
265 else if (format == GL_RGBA
266 || format == GL_RGBA8
267 || format == GL_RGBA16F_ARB
268 || format == GL_RGBA32F_ARB
269 || format == GL_BGRA)
273 VUserLog(
"Unknown format %s", formatString);
284 if (internalformat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
286 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT
287 || internalformat == GL_COMPRESSED_RED_RGTC1)
291 if (internalformat == GL_RGB
292 || internalformat == GL_RGBA
293 || internalformat == GL_RGBA8
294 || internalformat == GL_LUMINANCE8
295 || internalformat == GL_LUMINANCE8_ALPHA8)
297 else if (internalformat == GL_RGB16F_ARB
298 || internalformat == GL_RGBA16F_ARB
299 || internalformat == GL_DEPTH_COMPONENT
300 || internalformat == GL_LUMINANCE16F_ARB
301 || internalformat == GL_LUMINANCE_ALPHA16F_ARB)
303 else if (internalformat == GL_RGB32F_ARB
304 || internalformat == GL_RGBA32F_ARB
305 || internalformat == GL_LUMINANCE32F_ARB
306 || internalformat == GL_LUMINANCE_ALPHA32F_ARB)
320 if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT
321 || internalformat == GL_COMPRESSED_RED_RGTC1)
323 if (internalformat == GL_LUMINANCE8
324 || internalformat == GL_LUMINANCE
325 || internalformat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
327 if (internalformat == GL_LUMINANCE8_ALPHA8
328 || internalformat == GL_LUMINANCE16F_ARB
329 || internalformat == GL_DEPTH_COMPONENT)
331 if (internalformat == GL_RGB
332 || internalformat == GL_BGR)
334 if (internalformat == GL_RGBA
335 || internalformat == GL_RGBA8
336 || internalformat == GL_BGRA
337 || internalformat == GL_LUMINANCE_ALPHA16F_ARB
338 || internalformat == GL_LUMINANCE32F_ARB)
340 if (internalformat == GL_RGB16F_ARB)
342 if (internalformat == GL_RGBA16F_ARB
343 || internalformat == GL_LUMINANCE_ALPHA32F_ARB)
345 if (internalformat == GL_RGB32F_ARB)
347 if (internalformat == GL_RGBA32F_ARB)
351 VUserLog(
"Unknown internalformat %s", formatString);
363 if (format == GL_BGRA
364 || format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
365 || format == GL_LUMINANCE8_ALPHA8
366 || format == GL_LUMINANCE_ALPHA
367 || format == GL_LUMINANCE_ALPHA16F_ARB
368 || format == GL_LUMINANCE_ALPHA32F_ARB
370 || format == GL_RGBA16F_ARB
371 || format == GL_RGBA32F_ARB
372 || format == GL_RGBA8)
383 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
384 static unsigned long maximumTextureBytes = 0;
385 static dispatch_once_t maximumTextureBytesQuery = 0;
386 dispatch_once(&maximumTextureBytesQuery, ^{
387 GLint contextRendererID;
388 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &contextRendererID);
394 CGLRendererInfoObj ri;
395 GLint rendererCount = 0;
396 CGLQueryRendererInfo(-1, &ri, &rendererCount);
397 for (
int i = 0; i < rendererCount; ++i)
400 CGLDescribeRenderer(ri, i, kCGLRPRendererID, &rendererID);
401 if (rendererID == contextRendererID)
403 GLint textureMegabytes = 0;
404 if (CGLDescribeRenderer(ri, i, kCGLRPTextureMemoryMegabytes, &textureMegabytes) == kCGLNoError)
410 if ((rendererID & kCGLRendererIDMatchingMask) == kCGLRendererIntelHD4000ID)
414 maximumTextureBytes = (textureMegabytes - 85) * 1048576UL * fudge;
415 VDebugLog(
"%ld MB", maximumTextureBytes / 1024 / 1024);
420 CGLDestroyRendererInfo(ri);
422 return maximumTextureBytes;
430 static GLint maximumTextureDimension = 0;
431 static dispatch_once_t maximumTextureDimensionQuery = 0;
432 dispatch_once(&maximumTextureDimensionQuery, ^{
433 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
434 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maximumTextureDimension);
436 return maximumTextureDimension;
439 #pragma clang diagnostic push
440 #pragma clang diagnostic ignored "-Wunused-function"
446 return allocation == VuoGlTexturePool_NoAllocation ?
"NoAlloc" :
447 (allocation == VuoGlTexturePool_Allocate ?
"Alloc" :
448 allocation == VuoGlTexturePool_AllocateIOSurface ?
"AllocIOSurf" :
"?");
450 #pragma clang diagnostic pop
478 if (allocation == VuoGlTexturePool_AllocateIOSurface
479 && target != GL_TEXTURE_RECTANGLE_ARB)
481 VUserLog(
"Error: To use VuoGlTexturePool_AllocateIOSurface, target must be GL_TEXTURE_RECTANGLE_ARB.");
486 unsigned long requiredBytes = width * height * bytesPerPixel;
491 if (allocation != VuoGlTexturePool_AllocateIOSurface)
497 name = it->second.first.front();
498 it->second.first.pop();
506 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
512 if (maximumTextureBytes > 0)
514 if (requiredBytes > maximumTextureBytes)
517 VUserLog(
"Not enough graphics memory for a %dx%d (%d bytes/pixel) texture. Requires %lu MB, have %lu MB.", width, height, bytesPerPixel, requiredBytes/1024/1024, maximumTextureBytes/1024/1024);
524 if (width > maxDimension || height > maxDimension)
527 VUserLog(
"This GPU doesn't support textures of size %dx%d (GPU's limit is %dx%d).", width, height, maxDimension, maxDimension);
531 glGenTextures(1, &name);
533 glBindTexture(target, name);
534 if (allocation == VuoGlTexturePool_Allocate)
536 glTexImage2D(target, 0, internalformat, width, height, 0, format,
VuoGlTexture_getType(format), NULL);
539 else if (allocation == VuoGlTexturePool_AllocateIOSurface)
541 CGLError err = CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, internalformat, width, height, format,
VuoGlTexture_getType(format), (IOSurfaceRef)ioSurfaceRef, 0);
542 if (err != kCGLNoError)
544 VUserLog(
"Error in CGLTexImageIOSurface2D(): %s", CGLErrorString(err));
552 glBindTexture(target, name);
555 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
556 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
558 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
559 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
561 glBindTexture(target, 0);
578 if (internalformat == 0)
580 VUserLog(
"Error: Can't recycle texture %d since we don't know its internalformat. Deleting.", name);
582 glDeleteTextures(1, &name);
588 if (allocation == VuoGlTexturePool_AllocateIOSurface)
591 glDeleteTextures(1, &name);
601 auto it = &(*VuoGlTexturePool)[descriptor];
602 it->first.push(name);
619 unsigned int referenceCount;
621 void *freeCallbackContext;
643 if (glTextureName == 0)
650 (*VuoGlTexture_referenceCounts)[glTextureName] = (
VuoGlTexture){1, freeCallback, freeCallbackContext};
652 ++(*it).second.referenceCount;
666 if (glTextureName == 0)
673 VUserLog(
"Error: VuoGlTexture_release() was called with OpenGL Texture Object %d, which was never retained.", glTextureName);
676 VuoGlTexture t = (*VuoGlTexture_referenceCounts)[glTextureName];
677 if (--t.referenceCount == 0)
682 struct _VuoImage i = (
struct _VuoImage){glTextureName, internalformat, glTextureTarget, width, height, 1, t.freeCallbackContext, NULL, NULL, NULL};
711 if (glTextureName == 0)
718 VUserLog(
"Error: VuoGlTexture_disown() was called with OpenGL Texture Object %d, which was never retained.", glTextureName);
721 VuoGlTexture t = (*VuoGlTexture_referenceCounts)[glTextureName];
722 if (t.referenceCount != 1)
723 VUserLog(
"Error: VuoGlTexture_disown() was called with OpenGL Texture Object %d, which has a reference count of %d (but it should be 1).", glTextureName, t.referenceCount);
738 IOSurfaceRef ioSurface;
740 unsigned short pixelsWide;
741 unsigned short pixelsHigh;
800 unsigned long totalTextureCount = 0;
801 static unsigned long totalTextureCountMax = 0;
803 vector<GLuint> texturesToDelete;
804 vector<VuoIoSurfacePoolEntryType> iosurfaceTexturesToDisuse;
811 unsigned long textureCount = poolItem->second.first.size();
812 double timeSinceLastUsed = now - poolItem->second.second;
819 while (!poolItem->second.first.empty())
821 GLuint textureName = poolItem->second.first.front();
822 poolItem->second.first.pop();
823 texturesToDelete.push_back(textureName);
832 totalTextureCount += textureCount;
839 if (totalTextureCount > totalTextureCountMax)
840 totalTextureCountMax = totalTextureCount;
843 unsigned long totalIOSurfaceCount = 0;
844 static unsigned long totalIOSurfaceCountMax = 0;
851 for (deque<VuoIoSurfacePoolEntryType>::iterator quarantinedIoSurfaceEntry = quarantinedQueue->second.begin(); quarantinedIoSurfaceEntry != quarantinedQueue->second.end();)
859 (*VuoIoSurfacePool)[quarantinedQueue->first].push_back(e);
860 quarantinedIoSurfaceEntry = quarantinedQueue->second.erase(quarantinedIoSurfaceEntry);
866 ++totalIOSurfaceCount;
867 ++quarantinedIoSurfaceEntry;
876 for (deque<VuoIoSurfacePoolEntryType>::iterator poolIoSurfaceEntry = poolQueue->second.begin(); poolIoSurfaceEntry != poolQueue->second.end();)
883 CFRelease(e.ioSurface);
884 iosurfaceTexturesToDisuse.push_back(e);
885 poolIoSurfaceEntry = poolQueue->second.erase(poolIoSurfaceEntry);
889 ++totalIOSurfaceCount;
890 ++poolIoSurfaceEntry;
897 if (totalIOSurfaceCount > totalIOSurfaceCountMax)
898 totalIOSurfaceCountMax = totalIOSurfaceCount;
902 if (texturesToDelete.size())
904 for (vector<GLuint>::const_iterator i = texturesToDelete.begin(); i != texturesToDelete.end(); ++i)
907 glDeleteTextures(1, &t);
911 for (
auto e : iosurfaceTexturesToDisuse)
912 VuoGlTexturePool_disuse(VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, e.pixelsWide, e.pixelsHigh, e.texture);
917 static unsigned long cleanupCount = 0;
921 || totalTextureCount > 0 || totalTextureCountMax > 0
922 || totalIOSurfaceCount > 0 || totalIOSurfaceCountMax > 0))
924 __block
unsigned long maximumTextureBytes;
929 if (maximumTextureBytes > 0)
930 VUserLog(
"VRAM used: %5lu MB (%5lu MB max, %3lu%%). Textures in pool: %3lu (%3lu max). IOSurfaces in pool: %3lu (%3lu max).",
934 totalTextureCount, totalTextureCountMax,
935 totalIOSurfaceCount, totalIOSurfaceCountMax);
937 VUserLog(
"VRAM used: %5lu MB (%5lu MB max). Textures in pool: %3lu (%3lu max). IOSurfaces in pool: %3lu (%3lu max).",
940 totalTextureCount, totalTextureCountMax,
941 totalIOSurfaceCount, totalIOSurfaceCountMax);
944 static void __attribute__((constructor)) VuoGlPool_init(
void)
956 VuoGlPool_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
996 *outputTexture = e.texture;
997 (*VuoIoSurfacePool)[dimensions].pop_front();
1005 CFMutableDictionaryRef properties = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
1009 CFDictionaryAddValue(properties, kIOSurfaceIsGlobal, kCFBooleanTrue);
1011 long long pixelsWideLL = pixelsWide;
1012 CFNumberRef pixelsWideCF = CFNumberCreate(NULL, kCFNumberLongLongType, &pixelsWideLL);
1013 CFDictionaryAddValue(properties, kIOSurfaceWidth, pixelsWideCF);
1015 long long pixelsHighLL = pixelsHigh;
1016 CFNumberRef pixelsHighCF = CFNumberCreate(NULL, kCFNumberLongLongType, &pixelsHighLL);
1017 CFDictionaryAddValue(properties, kIOSurfaceHeight, pixelsHighCF);
1019 long long bytesPerElement = 4;
1020 CFNumberRef bytesPerElementCF = CFNumberCreate(NULL, kCFNumberLongLongType, &bytesPerElement);
1021 CFDictionaryAddValue(properties, kIOSurfaceBytesPerElement, bytesPerElementCF);
1023 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1027 e->ioSurface = IOSurfaceCreate(properties);
1028 e->pixelsWide = pixelsWide;
1029 e->pixelsHigh = pixelsHigh;
1030 e->lastUsedTime = -1;
1031 CFRelease(pixelsWideCF);
1032 CFRelease(pixelsHighCF);
1033 CFRelease(bytesPerElementCF);
1034 CFRelease(properties);
1036 *outputTexture =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, pixelsWide, pixelsHigh, GL_BGRA, e->ioSurface);
1037 e->texture = *outputTexture;
1051 return IOSurfaceGetID(e->ioSurface);
1060 return e->ioSurface;
1069 return e->pixelsWide;
1078 return e->pixelsHigh;
1112 (*VuoIoSurfaceQuarantine)[dimensions].push_back(*e);
1127 IOSurfaceRef ioSurface = (IOSurfaceRef)ios;
1140 int infologLength = 0;
1141 glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);
1142 if (infologLength > 0)
1144 char *infoLog = (
char *)malloc(infologLength);
1145 int charsWritten = 0;
1146 glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
1150 istringstream iss(infoLog);
1152 while (getline(iss, ln))
1155 char *message = (
char *)malloc(ln.length() + 1);
1156 char *quotation = (
char *)malloc(ln.length() + 1);
1157 if (sscanf(ln.c_str(),
"ERROR: 0:%d: '' : %[^\n]", &lineNumber, message) == 2)
1158 outIssues->
addIssue(stage, lineNumber, message);
1159 else if (sscanf(ln.c_str(),
"ERROR: 0:%d: '%[^']' : syntax error: %[^\n]", &lineNumber, quotation, message) == 3)
1160 outIssues->
addIssue(stage, lineNumber, message +
string(
": '") + quotation +
"'");
1161 else if (sscanf(ln.c_str(),
"ERROR: 0:%d: %[^\n]", &lineNumber, message) == 2)
1162 outIssues->
addIssue(stage, lineNumber, message);
1163 else if (sscanf(ln.c_str(),
"WARNING: 0:%d: %[^\n]", &lineNumber, message) == 2)
1164 outIssues->
addIssue(stage, lineNumber, message);
1167 VUserLog(
"Warning: Couldn't parse GLSL log message: \"%s\"", ln.c_str());
1184 map<GLenum, map<long, GLuint> > VuoGlShaderPool
__attribute__((init_priority(101)));
1190 __attribute__((constructor))
static void VuoGlShaderPool_init(
void)
1207 userModulesPath =
"";
1210 systemModulesPath =
"";
1212 set<string> includedFiles;
1216 const string includeKeyword =
"#include";
1218 size_t includeStart = source.find(includeKeyword);
1219 if (includeStart == string::npos)
1222 size_t offset = includeStart + includeKeyword.length();
1224 while (source[offset] ==
' ')
1227 if (source[offset] !=
'"'
1228 && source[offset] !=
'<')
1234 VUserLog(
"Error: Syntax error in #include statement. Expected syntax: #include \"filename.glsl\"");
1239 size_t filenameStart = offset;
1241 while (source[offset] !=
'"'
1242 && source[offset] !=
'>')
1245 size_t filenameEnd = offset;
1247 string filename = source.substr(filenameStart, filenameEnd - filenameStart);
1249 vector<string> pathsToTest;
1250 if (strcmp(cwd,
"/") != 0)
1251 pathsToTest.push_back(cwd +
string(
"/") + filename);
1252 if (!vuoFrameworkPath.empty())
1253 pathsToTest.push_back(vuoFrameworkPath +
"/Resources/shaders/" + filename);
1254 if (!vuoRunnerFrameworkPath.empty())
1255 pathsToTest.push_back(vuoRunnerFrameworkPath +
"/Resources/shaders/" + filename);
1256 if (!userModulesPath.empty())
1257 pathsToTest.push_back(userModulesPath +
"/" + filename);
1258 if (!systemModulesPath.empty())
1259 pathsToTest.push_back(systemModulesPath +
"/" + filename);
1261 for (vector<string>::iterator i = pathsToTest.begin(); i != pathsToTest.end(); ++i)
1267 source.erase(includeStart, offset - includeStart + 1);
1270 if (includedFiles.count(*i))
1272 source.insert(includeStart,
1274 "// ============================================================\n"
1275 "// Skipped including file \"" + *i +
"\" since it was already included.\n"
1276 "// ============================================================\n"
1281 includedFiles.insert(*i);
1283 source.insert(includeStart,
1285 "// ============================================================\n"
1286 "// Begin included file \"" + *i +
"\"\n"
1289 "// End included file \"" + *i +
"\"\n"
1290 "// ============================================================\n"
1303 VUserLog(
"Error: Couldn't find include file \"%s\".", filename.c_str());
1336 if (!outIssues && VuoGlShaderPool[type].find(hash) != VuoGlShaderPool[type].end())
1337 shader = VuoGlShaderPool[type][hash];
1340 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1342 string combinedSource = source;
1346 if (type == GL_VERTEX_SHADER)
1347 stage = VuoShaderFile::Vertex;
1348 else if (type == GL_GEOMETRY_SHADER_EXT)
1349 stage = VuoShaderFile::Geometry;
1351 stage = VuoShaderFile::Fragment;
1361 shader = glCreateShader(type);
1362 GLint length = combinedSource.length();
1363 const GLchar *combinedSourceCString = combinedSource.c_str();
1364 glShaderSource(shader, 1, (
const GLchar**)&combinedSourceCString, &length);
1365 glCompileShader(shader);
1368 GLint status = GL_FALSE;
1369 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
1370 if (status == GL_FALSE)
1372 glDeleteShader(shader);
1377 VuoGlShaderPool[type][hash] = shader;
1391 static void __attribute__((constructor)) VuoGlProgramPool_init(
void)
1419 VuoGlProgramDescriptorType e(vertexShaderName, std::make_pair(geometryShaderName, std::make_pair(fragmentShaderName, std::make_pair(assemblyMethod, expectedOutputPrimitiveCount))));
1423 program = it->second;
1426 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1428 GLuint programName = glCreateProgram();
1429 glAttachShader(programName, vertexShaderName);
1430 if (geometryShaderName)
1431 glAttachShader(programName, geometryShaderName);
1432 if (fragmentShaderName)
1433 glAttachShader(programName, fragmentShaderName);
1435 bool transformFeedback =
false;
1437 if (!fragmentShaderName)
1438 transformFeedback =
true;
1441 glBindAttribLocation(programName, 0,
"position");
1443 if (geometryShaderName)
1445 GLuint inputPrimitiveGlMode = GL_TRIANGLES;
1448 inputPrimitiveGlMode = GL_LINES;
1450 inputPrimitiveGlMode = GL_POINTS;
1451 glProgramParameteriEXT(programName, GL_GEOMETRY_INPUT_TYPE_EXT, inputPrimitiveGlMode);
1453 GLuint outputPrimitiveGlMode = GL_TRIANGLE_STRIP;
1454 if (transformFeedback)
1459 outputPrimitiveGlMode = GL_LINE_STRIP;
1461 outputPrimitiveGlMode = GL_POINTS;
1463 glProgramParameteriEXT(programName, GL_GEOMETRY_OUTPUT_TYPE_EXT, outputPrimitiveGlMode);
1465 unsigned int expectedVertexCount = expectedOutputPrimitiveCount;
1466 if (outputPrimitiveGlMode == GL_TRIANGLE_STRIP)
1467 expectedVertexCount *= 3;
1468 else if (outputPrimitiveGlMode == GL_LINE_STRIP)
1469 expectedVertexCount *= 2;
1470 glProgramParameteriEXT(programName, GL_GEOMETRY_VERTICES_OUT_EXT, expectedVertexCount);
1473 if (transformFeedback)
1475 const GLchar *varyings[] = {
"outPosition",
"outNormal",
"outTextureCoordinate",
"outVertexColor" };
1476 glTransformFeedbackVaryingsEXT(programName, 4, varyings, GL_SEPARATE_ATTRIBS_EXT);
1479 glLinkProgram(programName);
1482 int infologLength = 0;
1483 glGetProgramiv(programName, GL_INFO_LOG_LENGTH, &infologLength);
1484 if (infologLength > 0)
1486 char *infoLog = (
char *)malloc(infologLength);
1487 int charsWritten = 0;
1488 glGetProgramInfoLog(programName, infologLength, &charsWritten, infoLog);
1494 istringstream iss(infoLog);
1496 while (getline(iss, ln))
1505 VUserLog(
"Warning: Couldn't parse GLSL log message: \"%s\"", ln.c_str());
1511 VUserLog(
"%s: %s", description, infoLog);
1518 glGetProgramiv(programName, GL_LINK_STATUS, &linkStatus);
1519 if (linkStatus == GL_FALSE)
1521 glDeleteProgram(programName);
1526 program.programName = programName;
1529 glGetProgramiv(programName, GL_ACTIVE_UNIFORMS, &uniformCount);
1531 GLint maxNameLength;
1532 glGetProgramiv(programName, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
1533 char *name = (
char *)malloc(maxNameLength + 1);
1536 program.uniforms = (
void *)uniforms;
1538 for (GLuint i = 0; i < uniformCount; ++i)
1541 glGetActiveUniform(programName, i, maxNameLength+1, NULL, &size, NULL, name);
1544 size_t nameLen = strlen(name);
1546 (*uniforms)[hash] = glGetUniformLocation(programName, name);
1552 if (name[nameLen-2] ==
'0' && name[nameLen-1] ==
']')
1554 name[nameLen-2] = 0;
1555 for (
int i = 1; i < size; ++i)
1557 std::stringstream ss;
1558 ss << name << i <<
"]";
1559 string sss = ss.str();
1561 (*uniforms)[sHash] = glGetUniformLocation(programName, sss.c_str());
1581 long hash =
VuoGlPool_collate.hash(uniformIdentifier, uniformIdentifier+strlen(uniformIdentifier));
1583 VuoGlUniformMap::iterator i = uniforms->find(hash);
1584 if (i != uniforms->end())
1591 #define RETURN_STRING_IF_EQUAL(value) if (constant == value) return strdup(#value)
1601 return strdup(
"(GL_ZERO or GL_POINTS)");
1603 return strdup(
"(GL_ONE or GL_LINES)");