20#include <CoreFoundation/CoreFoundation.h>
22#include <IOSurface/IOSurfaceAPI.h>
24#include <OpenGL/OpenGL.h>
25#include <OpenGL/CGLMacro.h>
37 "description" :
"An image residing in GPU memory (GL Texture Object).",
51 "CoreFoundation.framework",
72 if (t->cpuQueueInitialized && json_object_object_length(t->cpuData))
75 glBindTexture(t->glTextureTarget, t->glTextureName);
76 GLenum format = GL_BGRA;
77 if (t->glInternalFormat == GL_DEPTH_COMPONENT)
78 format = GL_DEPTH_COMPONENT;
81 glTexImage2D(t->glTextureTarget, 0, t->glInternalFormat, t->pixelsWide, t->pixelsHigh, 0, format, type, NULL);
82 glBindTexture(t->glTextureTarget, 0);
86 VuoGlTexture_release(VuoGlTexturePool_Allocate, t->glTextureTarget, t->glInternalFormat, t->pixelsWide, t->pixelsHigh, t->glTextureName);
88 if (t->cpuQueueInitialized)
90 dispatch_release(t->cpuQueue);
92 json_object_object_foreach(t->cpuData, key, value)
96 json_object_object_get_ex(value,
"buffer", &o);
97 void *buffer = (
void *)json_object_get_int64(o);
99 json_object_object_get_ex(value,
"freeCallback", &o);
100 void (^freeCallback)(
void *) = (
void (^)(
void *))json_object_get_int64(o);
102 freeCallback(buffer);
104 Block_release(freeCallback);
107 json_object_put(t->cpuData);
121 t->glTextureName = glTextureName;
122 t->glTextureTarget = GL_TEXTURE_2D;
123 t->glInternalFormat = glInternalFormat;
124 t->pixelsWide = pixelsWide;
125 t->pixelsHigh = pixelsHigh;
128 t->freeCallbackContext = freeCallbackContext;
132 t->cpuQueueInitialized = 0;
156VuoImage VuoImage_make(
unsigned int glTextureName,
unsigned int glInternalFormat,
unsigned long int pixelsWide,
unsigned long int pixelsHigh)
158 if (!glTextureName || !pixelsWide || !pixelsHigh)
189 if (!glTextureName || !pixelsWide || !pixelsHigh)
192 return VuoImage_make_internal(glTextureName, glInternalFormat, pixelsWide, pixelsHigh, freeCallback, freeCallbackContext);
225 t->glTextureTarget = GL_TEXTURE_RECTANGLE_ARB;
263 if (!pixelsWide || !pixelsHigh)
266 __block GLenum internalformat;
267 __block GLuint glTextureName;
268 __block
int alignment = 1;
269 __block
bool customRowLength =
false;
274 glTextureName =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, internalformat, pixelsWide, pixelsHigh, format, NULL);
280 if (colorDepth == VuoImageColorDepth_8)
282 else if (colorDepth == VuoImageColorDepth_16)
284 glType = GL_HALF_FLOAT_ARB;
294 || bytesPerRow == bytesPerPixel * pixelsWide)
299 if (bytesPerRow % 4 == 0)
301 else if (bytesPerRow % 8 == 0)
303 else if (bytesPerRow % 2 == 0)
305 else if (bytesPerRow % bytesPerPixel == 0)
307 GLuint rowPixels = bytesPerRow / bytesPerPixel;
308 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowPixels);
309 customRowLength =
true;
313 VUserLog(
"Not sure how to handle this stride:");
314 VUserLog(
" %dx%d",pixelsWide,pixelsHigh);
315 VUserLog(
" bytesPerRow = %d",bytesPerRow);
316 VUserLog(
" bytesPerPixel = %d",bytesPerPixel);
317 GLint leftoverBytes = bytesPerRow - bytesPerPixel*pixelsWide;
318 VUserLog(
" leftoverBytes = %d",leftoverBytes);
323 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
325 glBindTexture(GL_TEXTURE_2D, glTextureName);
326 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
328 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, pixelsWide, pixelsHigh, 0, format, glType, (GLvoid *)pixels);
329 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE);
330 glBindTexture(GL_TEXTURE_2D, 0);
333 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
335 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
340 glFlushRenderAPPLE();
349 dispatch_once(&image->cpuQueueInitialized, ^{});
350 image->cpuQueue = dispatch_queue_create(
"org.vuo.image.cpu", NULL);
351 image->cpuData = json_object_new_object();
355 char *keyWithAlignment;
356 asprintf(&keyWithAlignment,
"%s alignment=%d", key, alignment);
358 key = keyWithAlignment;
362 char *keyWithRowLength;
363 asprintf(&keyWithRowLength,
"%s rowLength=%d", key, bytesPerRow);
365 key = keyWithRowLength;
368 json_object_object_add(cpuEntry,
"buffer", json_object_new_int64((
long long)pixels));
369 json_object_object_add(cpuEntry,
"freeCallback", json_object_new_int64((
long long)Block_copy(freeCallback)));
370 json_object_object_add(image->cpuData, key, cpuEntry);
406 if (image->glInternalFormat == GL_DEPTH_COMPONENT && requestedFormat != GL_DEPTH_COMPONENT16)
408 VUserLog(
"Error: Image has format GL_DEPTH_COMPONENT, which must be fetched as GL_DEPTH_COMPONENT16.");
412 dispatch_once(&image->cpuQueueInitialized, ^{
413 image->cpuQueue = dispatch_queue_create(
"org.vuo.image.cpu", NULL);
414 image->cpuData = json_object_new_object();
417 __block
unsigned char *pixels = NULL;
418 dispatch_sync(image->cpuQueue, ^{
419 char *key = VuoGl_stringForConstant(requestedFormat);
420 struct json_object *value;
421 if (json_object_object_get_ex(image->cpuData, key, &value))
424 json_object_object_get_ex(value,
"buffer", &o);
425 pixels = (unsigned char *)json_object_get_int64(o);
429 unsigned int channels;
430 if (requestedFormat == GL_LUMINANCE
431 || requestedFormat == GL_R16
432 || requestedFormat == GL_DEPTH_COMPONENT16)
434 else if (requestedFormat == GL_LUMINANCE_ALPHA)
436 else if (requestedFormat == GL_RGB
437 || requestedFormat == GL_BGR)
439 else if (requestedFormat == GL_RGBA
440 || requestedFormat == GL_BGRA
441 || requestedFormat == GL_RGBA16I_EXT
442 || requestedFormat == GL_RGBA16F_ARB
443 || requestedFormat == GL_RGBA32F_ARB)
447 VUserLog(
"Error: Unknown format %s.", VuoGl_stringForConstant(requestedFormat));
451 unsigned int bytesPerChannel = 1;
452 GLuint type = GL_UNSIGNED_BYTE;
453 if (requestedFormat == GL_RGBA16I_EXT
454 || requestedFormat == GL_R16
455 || requestedFormat == GL_DEPTH_COMPONENT16)
458 type = GL_UNSIGNED_SHORT;
460 else if (requestedFormat == GL_RGBA16F_ARB)
463 type = GL_HALF_FLOAT_ARB;
465 else if (requestedFormat == GL_RGBA32F_ARB)
471 GLuint actualFormat = requestedFormat;
472 if (requestedFormat == GL_RGBA16I_EXT
473 || requestedFormat == GL_RGBA16F_ARB
474 || requestedFormat == GL_RGBA32F_ARB)
475 actualFormat = GL_BGRA;
476 else if (requestedFormat == GL_DEPTH_COMPONENT16)
477 actualFormat = GL_DEPTH_COMPONENT;
478 else if (requestedFormat == GL_R16)
479 actualFormat = GL_RED;
481 size_t pixelBufferSize = image->pixelsWide * image->pixelsHigh * channels * bytesPerChannel;
482 pixels = (
unsigned char *)malloc(pixelBufferSize);
486 const char *tamperEvidentSeal =
"Vuo\0Ima\0ge_\0get\0Buf\0fer\0()\0";
487 int tamperEvidentSealLength = strlen(tamperEvidentSeal);
488 if (pixelBufferSize > tamperEvidentSealLength)
489 strlcpy((
char *)pixels, tamperEvidentSeal, pixelBufferSize);
494 bool openGLAddsPadding = ((image->pixelsWide * channels * bytesPerChannel) % 4 != 0);
495 if (openGLAddsPadding)
497 glPixelStorei(GL_PACK_ALIGNMENT, 1);
499 glBindTexture(image->glTextureTarget, image->glTextureName);
501 glGetTexImage(image->glTextureTarget, 0, actualFormat, type, (GLvoid *)pixels);
502 glBindTexture(image->glTextureTarget, 0);
504 if (openGLAddsPadding)
506 glPixelStorei(GL_PACK_ALIGNMENT, 4);
508 if (pixelBufferSize > tamperEvidentSealLength && strncmp((
char *)pixels, tamperEvidentSeal, strlen(tamperEvidentSeal)) == 0)
510 GLenum error = glGetError();
511 if (error == GL_NO_ERROR)
515 VUserLog(
"Warning: glGetTexImage() says it was successful, but it didn't actually copy any data. This might happen if the input texture has an IOSurface bound to it.");
517 VUserLog(
"OpenGL Error: %d", error);
528 json_object_object_add(cpuEntry,
"buffer", json_object_new_int64((
long long)pixels));
529 json_object_object_add(cpuEntry,
"freeCallback", json_object_new_int64((
long long)Block_copy( ^(
void *buffer){ free(buffer); } )));
530 json_object_object_add(image->cpuData, key, cpuEntry);
544 __block GLint wrapModeGL;
547 glBindTexture(image->glTextureTarget, image->glTextureName);
549 glGetTexParameteriv(image->glTextureTarget, GL_TEXTURE_WRAP_S, &wrapModeGL);
552 glBindTexture(image->glTextureTarget, 0);
556 if (wrapModeGL == GL_CLAMP_TO_EDGE)
557 return VuoImageWrapMode_ClampEdge;
558 else if (wrapModeGL == GL_REPEAT)
559 return VuoImageWrapMode_Repeat;
560 else if (wrapModeGL == GL_MIRRORED_REPEAT)
561 return VuoImageWrapMode_MirroredRepeat;
563 return VuoImageWrapMode_None;
573 glBindTexture(image->glTextureTarget, image->glTextureName);
575 GLint wrapModeGL = GL_CLAMP_TO_BORDER;
576 if (wrapMode == VuoImageWrapMode_ClampEdge)
577 wrapModeGL = GL_CLAMP_TO_EDGE;
578 else if (wrapMode == VuoImageWrapMode_Repeat)
579 wrapModeGL = GL_REPEAT;
580 else if (wrapMode == VuoImageWrapMode_MirroredRepeat)
581 wrapModeGL = GL_MIRRORED_REPEAT;
583 glTexParameteri(image->glTextureTarget, GL_TEXTURE_WRAP_S, wrapModeGL);
584 glTexParameteri(image->glTextureTarget, GL_TEXTURE_WRAP_T, wrapModeGL);
586 glBindTexture(image->glTextureTarget, 0);
590 glFlushRenderAPPLE();
600 if (!pixelsWide || !pixelsHigh)
624 if (image->glTextureTarget == GL_TEXTURE_2D)
626 else if (image->glTextureTarget == GL_TEXTURE_RECTANGLE_ARB)
636 shader->isTransparent =
true;
639 forcePixelsWide ? forcePixelsWide : image->pixelsWide,
640 forcePixelsHigh ? forcePixelsHigh : image->pixelsHigh,
658 GLuint textureName = VuoImageRenderer_draw_internal(frag, image->pixelsWide, image->pixelsHigh,
VuoImage_getColorDepth(image),
false,
true, 0, NULL);
661 img->glTextureTarget = GL_TEXTURE_RECTANGLE_ARB;
678 if (a->pixelsWide != b->pixelsWide
679 || a->pixelsHigh != b->pixelsHigh)
682 if (a->glTextureName == b->glTextureName)
690 if (aChannels == 4 && bChannels == 1)
693 for (
unsigned int i = 0; i < a->pixelsWide * a->pixelsHigh; ++i)
694 if (abs(aPixels[i*4+0] - bPixels[i*4+2]) > tolerance
695 || abs(aPixels[i*4+1] - bPixels[i*4+2]) > tolerance
696 || abs(aPixels[i*4+2] - bPixels[i*4+2]) > tolerance
697 || abs(aPixels[i*4+3] - bPixels[i*4+3]) > tolerance)
699 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): RGBA %d,%d,%d,%d vs %d,%d,%d,%d",
700 i%a->pixelsWide, i/a->pixelsWide,
701 aPixels[i*4+2],aPixels[i*4+1],aPixels[i*4+0],aPixels[i*4+3],
702 bPixels[i*4+2],bPixels[i*4+2],bPixels[i*4+2],bPixels[i*4+3]);
707 else if (aChannels == 1 && bChannels == 4)
710 for (
unsigned int i = 0; i < a->pixelsWide * a->pixelsHigh; ++i)
711 if (abs(aPixels[i*4+2] - bPixels[i*4+0]) > tolerance
712 || abs(aPixels[i*4+2] - bPixels[i*4+1]) > tolerance
713 || abs(aPixels[i*4+2] - bPixels[i*4+2]) > tolerance
714 || abs(aPixels[i*4+3] - bPixels[i*4+3]) > tolerance)
716 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): RGBA %d,%d,%d,%d vs %d,%d,%d,%d",
717 i%a->pixelsWide, i/a->pixelsWide,
718 aPixels[i*4+2],aPixels[i*4+2],aPixels[i*4+2],aPixels[i*4+3],
719 bPixels[i*4+2],bPixels[i*4+1],bPixels[i*4+0],bPixels[i*4+3]);
725 for (
unsigned int i = 0; i < a->pixelsWide * a->pixelsHigh * 4; ++i)
726 if (abs(aPixels[i] - bPixels[i]) > tolerance)
728 unsigned int p = (i/4)*4;
729 VDebugLog(
"Difference found at pixel coordinate (%ld,%ld): abs(%d - %d) > %d (RGBA %d,%d,%d,%d vs %d,%d,%d,%d)",
730 i%a->pixelsWide, i/a->pixelsWide,
731 aPixels[i], bPixels[i], tolerance,
732 aPixels[p+2],aPixels[p+1],aPixels[p+0],aPixels[p+3],
733 bPixels[p+2],bPixels[p+1],bPixels[p+0],bPixels[p+3]);
768 if (a->pixelsWide < b->pixelsWide)
return true;
769 if (b->pixelsWide < a->pixelsWide)
return false;
771 if (a->pixelsHigh < b->pixelsHigh)
return true;
782 if (!image || image->pixelsWide == 0 || image->pixelsHigh == 0)
786 bool foundSubstantialPixel =
false;
787 for (
unsigned int p = 3; p < image->pixelsWide * image->pixelsHigh * 4; p += 4)
790 foundSubstantialPixel =
true;
793 return !foundSubstantialPixel;
804 if (!image || image->pixelsWide == 0 || image->pixelsHigh == 0)
808 bool foundNonBlackPixel =
false;
809 for (
unsigned int p = 0; p < image->pixelsWide * image->pixelsHigh; ++p)
810 if (pixels[p] > tolerance)
812 foundNonBlackPixel =
true;
815 return !foundNonBlackPixel;
825 return (image && image->pixelsWide && image->pixelsHigh);
842 return VuoImageColorDepth_8;
844 if (image->glInternalFormat == GL_LUMINANCE8
845 || image->glInternalFormat == GL_LUMINANCE8_ALPHA8
846 || image->glInternalFormat == GL_RGB
847 || image->glInternalFormat == GL_RGBA
848 || image->glInternalFormat == GL_RGBA8
849 || image->glInternalFormat == GL_BGRA
850 || image->glInternalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT
851 || image->glInternalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
852 return VuoImageColorDepth_8;
853 else if (image->glInternalFormat == GL_LUMINANCE16F_ARB
854 || image->glInternalFormat == GL_LUMINANCE_ALPHA16F_ARB
855 || image->glInternalFormat == GL_DEPTH_COMPONENT
856 || image->glInternalFormat == GL_RGB16
857 || image->glInternalFormat == GL_RGBA16
858 || image->glInternalFormat == GL_RGB16F_ARB
859 || image->glInternalFormat == GL_RGBA16F_ARB)
860 return VuoImageColorDepth_16;
861 else if (image->glInternalFormat == GL_LUMINANCE32F_ARB
862 || image->glInternalFormat == GL_LUMINANCE_ALPHA32F_ARB
863 || image->glInternalFormat == GL_RGB32F_ARB
864 || image->glInternalFormat == GL_RGBA32F_ARB)
865 return VuoImageColorDepth_32;
868 VUserLog(
"Error: Unknown glInternalFormat %x (%s)", image->glInternalFormat, formatString);
870 return VuoImageColorDepth_8;
920 VuoGlTexturePool_disuse(VuoGlTexturePool_AllocateIOSurface, i->glTextureTarget, i->glInternalFormat, i->pixelsWide, i->pixelsHigh, i->glTextureName);
949 if (json_object_object_get_ex(js,
"pointer", &o))
952 if ((requestedPixelsWide == 0 && requestedPixelsHigh == 0)
953 || (im->pixelsWide == requestedPixelsWide && im->pixelsHigh == requestedPixelsHigh))
960 VuoImage outputImage =
VuoImage_make(im->glTextureName, im->glInternalFormat, requestedPixelsWide, requestedPixelsHigh);
961 outputImage->glTextureTarget = im->glTextureTarget;
962 outputImage->scaleFactor = im->scaleFactor;
969 __block
unsigned int glInternalFormat = 0;
970 unsigned long int pixelsWide;
971 unsigned long int pixelsHigh;
972 float scaleFactor = 1;
976 if (json_object_object_get_ex(js,
"pixelsWide", &o))
977 pixelsWide = json_object_get_int64(o);
983 if (json_object_object_get_ex(js,
"pixelsHigh", &o))
984 pixelsHigh = json_object_get_int64(o);
988 if (pixelsWide == 0 || pixelsHigh == 0)
993 if (json_object_object_get_ex(js,
"scaleFactor", &o))
994 scaleFactor = json_object_get_double(o);
999 if (json_object_object_get_ex(js,
"color", &o))
1005 if (json_object_object_get_ex(js,
"ioSurface", &o))
1007 IOSurfaceID surfID = json_object_get_int(o);
1011 __block IOSurfaceRef surf = NULL;
1012 __block GLuint textureRect;
1014 glInternalFormat = GL_RGBA;
1015 surf = IOSurfaceLookup(surfID);
1018 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1021 textureRect =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, glInternalFormat, pixelsWide, pixelsHigh, GL_BGRA, surf);
1022 glFlushRenderAPPLE();
1032 imageRect->glTextureTarget = GL_TEXTURE_RECTANGLE_ARB;
1039 requestedPixelsWide ? requestedPixelsWide : pixelsWide,
1040 requestedPixelsHigh ? requestedPixelsHigh : pixelsHigh,
1047 image2d->scaleFactor = scaleFactor;
1080 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1082 *outputPixelsWide = json_object_get_int64(o);
1084 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1086 *outputPixelsHigh = json_object_get_int64(o);
1088 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1090 IOSurfaceID surfID = json_object_get_int(o);
1092 GLuint textureRect = provider(*outputPixelsWide, *outputPixelsHigh);
1097 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureRect);
1099 IOSurfaceRef *surf = outputIOSurface;
1100 *surf = IOSurfaceLookup(surfID);
1103 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1107 CGLError err = CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, (GLsizei)*outputPixelsWide, (GLsizei)*outputPixelsHigh, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, *surf, 0);
1108 if(err != kCGLNoError)
1110#pragma clang diagnostic push
1111#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1112 VUserLog(
"Error in CGLTexImageIOSurface2D(): %s", CGLErrorString(err));
1113#pragma clang diagnostic pop
1116 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1117 glFlushRenderAPPLE();
1148 if (!clientTextureName)
1153 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1155 unsigned long inputPixelsWide = json_object_get_int64(o);
1157 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1159 unsigned long inputPixelsHigh = json_object_get_int64(o);
1161 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1163 IOSurfaceID surfID = json_object_get_int(o);
1165 __block
bool success =
true;
1167 IOSurfaceRef *surf = outputIOSurface;
1168 *surf = IOSurfaceLookup(surfID);
1171 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1176 bool shouldResize = (inputPixelsWide != pixelsWide
1177 || inputPixelsHigh != pixelsHigh);
1182 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, clientTextureName);
1183 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, pixelsWide, pixelsHigh, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1184 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1186 GLuint outputFramebuffer;
1187 glGenFramebuffers(1, &outputFramebuffer);
1188 glBindFramebuffer(GL_FRAMEBUFFER, outputFramebuffer);
1189 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, clientTextureName, 0);
1191 glViewport(0, 0, pixelsWide, pixelsHigh);
1195 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 0, 0);
1196 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1197 glDeleteFramebuffers(1, &outputFramebuffer);
1201 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, clientTextureName);
1203 CGLError err = CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, (GLsizei)inputPixelsWide, (GLsizei)inputPixelsHigh, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, *surf, 0);
1204 if (err != kCGLNoError)
1206#pragma clang diagnostic push
1207#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1208 VUserLog(
"Error in CGLTexImageIOSurface2D(): %s", CGLErrorString(err));
1209#pragma clang diagnostic pop
1214 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1217 glFlushRenderAPPLE();
1241 if (!json_object_object_get_ex(js,
"pixelsWide", &o))
1243 GLsizei pixelsWide = json_object_get_int64(o);
1245 if (!json_object_object_get_ex(js,
"pixelsHigh", &o))
1247 GLsizei pixelsHigh = json_object_get_int64(o);
1249 if (!json_object_object_get_ex(js,
"ioSurface", &o))
1251 IOSurfaceID surfID = json_object_get_int(o);
1252 IOSurfaceRef surf = IOSurfaceLookup(surfID);
1255 VUserLog(
"Error: IOSurfaceLookup(%d) failed.", surfID);
1270static GLuint
CompileShader(CGLContextObj cgl_ctx, GLenum type,
const char *source)
1272 GLint length = (GLint)strlen(source);
1273 GLuint shader = glCreateShader(type);
1274 glShaderSource(shader, 1, (
const GLchar**)&source, &length);
1275 glCompileShader(shader);
1277 int infologLength = 0;
1278 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
1279 if (infologLength > 0)
1281 char *infoLog = (
char *)malloc(infologLength);
1282 int charsWritten = 0;
1283 glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
1298 CGLContextObj cgl_ctx = (CGLContextObj)context;
1300 static bool openGL32Core;
1301 static GLuint vertexArray;
1302 static GLuint program;
1303 static GLuint receiveTextureOffsetAndSizeUniform;
1307 char *vertexShaderSource;
1308 char *fragmentShaderSource;
1312 CGLSetCurrentContext(cgl_ctx);
1319 in vec2 textureCoordinate;
1320 out vec2 fragmentTextureCoordinate;
1323 fragmentTextureCoordinate = textureCoordinate;
1324 gl_Position = vec4(position.x, position.y, 0., 1.);
1328 uniform sampler2DRect receiveTexture;
1329 uniform vec4 receiveTextureOffsetAndSize;
1330 in vec2 fragmentTextureCoordinate;
1334 FragColor = texture(receiveTexture, receiveTextureOffsetAndSize.xy + fragmentTextureCoordinate * receiveTextureOffsetAndSize.zw);
1342 glGenVertexArraysAPPLE(1, &vertexArray);
1343 glBindVertexArrayAPPLE(vertexArray);
1346 attribute vec2 position;
1347 attribute vec2 textureCoordinate;
1348 varying vec2 fragmentTextureCoordinate;
1351 fragmentTextureCoordinate = textureCoordinate;
1352 gl_Position = vec4(position.x, position.y, 0., 1.);
1356 uniform sampler2DRect receiveTexture;
1357 uniform vec4 receiveTextureOffsetAndSize;
1358 varying vec2 fragmentTextureCoordinate;
1361 gl_FragColor = texture2DRect(receiveTexture, receiveTextureOffsetAndSize.xy + fragmentTextureCoordinate * receiveTextureOffsetAndSize.zw);
1367 const GLfloat quadPositionsAndTextureCoordinates[] = {
1377 GLuint quadPTCBuffer;
1378 glGenBuffers(1, &quadPTCBuffer);
1379 glBindBuffer(GL_ARRAY_BUFFER, quadPTCBuffer);
1380 glBufferData(GL_ARRAY_BUFFER,
sizeof(quadPositionsAndTextureCoordinates), quadPositionsAndTextureCoordinates, GL_STATIC_DRAW);
1383 GLuint vertexShader =
CompileShader(context, GL_VERTEX_SHADER, vertexShaderSource);
1384 GLuint fragmentShader =
CompileShader(context, GL_FRAGMENT_SHADER, fragmentShaderSource);
1385 program = glCreateProgram();
1386 glAttachShader(program, vertexShader);
1387 glAttachShader(program, fragmentShader);
1388 glLinkProgram(program);
1389 GLuint positionAttribute = glGetAttribLocation(program,
"position");
1390 GLuint textureCoordinateAttribute = glGetAttribLocation(program,
"textureCoordinate");
1391 GLuint receiveTextureUniform = glGetUniformLocation(program,
"receiveTexture");
1392 receiveTextureOffsetAndSizeUniform = glGetUniformLocation(program,
"receiveTextureOffsetAndSize");
1394 glUseProgram(program);
1396 glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat)*4, (
void*)0);
1397 glEnableVertexAttribArray(positionAttribute);
1399 glVertexAttribPointer(textureCoordinateAttribute, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat)*4, (
void*)(
sizeof(GLfloat)*2));
1400 glEnableVertexAttribArray(textureCoordinateAttribute);
1402 glUniform1i(receiveTextureUniform, 0);
1408 CGLSetCurrentContext(cgl_ctx);
1412 glBindVertexArrayAPPLE(vertexArray);
1414 GLuint textureRect =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, pixelsWide, pixelsHigh, GL_BGRA, surf);
1417 VUserLog(
"Error: Couldn't allocate texture.");
1423 glActiveTexture(GL_TEXTURE0);
1424 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textureRect);
1426 glUseProgram(program);
1429 glUniform4f(receiveTextureOffsetAndSizeUniform, 0, flip ? pixelsHigh : 0, pixelsWide, pixelsHigh * (flip ? -1 : 1));
1434 glGetIntegerv(GL_VIEWPORT, viewport);
1436 glUniform4f(receiveTextureOffsetAndSizeUniform,
1437 ((
float)pixelsWide - viewport[2]) / 2,
1438 flip ? viewport[3] : 0,
1440 viewport[3] * (flip ? -1 : 1));
1443 glDrawArrays(GL_TRIANGLES, 0, 6);
1445 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1446 VuoGlTexture_release(VuoGlTexturePool_AllocateIOSurface, GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, pixelsWide, pixelsHigh, textureRect);
1451 glBindVertexArrayAPPLE(0);
1453 glBindBuffer(GL_ARRAY_BUFFER, 0);
1472 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1490 __block IOSurfaceID surfID = 0;
1494 if (value->glTextureTarget == GL_TEXTURE_2D)
1496 else if (value->glTextureTarget == GL_TEXTURE_RECTANGLE_ARB)
1500 surfID = VuoImageRenderer_draw_internal(shader, value->pixelsWide, value->pixelsHigh,
VuoImage_getColorDepth(value),
true,
true, 0, NULL);
1505 glFlushRenderAPPLE();
1513 json_object_object_add(js,
"ioSurface", o);
1517 json_object * o = json_object_new_int64(value->pixelsWide);
1518 json_object_object_add(js,
"pixelsWide", o);
1521 json_object * o = json_object_new_int64(value->pixelsHigh);
1522 json_object_object_add(js,
"pixelsHigh", o);
1525 json_object *o = json_object_new_double(value->scaleFactor);
1526 json_object_object_add(js,
"scaleFactor", o);
1548 return strdup(
"No image");
1551 switch (value->glInternalFormat)
1553 case GL_RGB: type =
"RGB, each channel 8-bit unsigned integer";
break;
1554 case GL_RGB16F_ARB: type =
"RGB, each channel 16-bit signed float";
break;
1555 case GL_RGB32F_ARB: type =
"RGB, each channel 32-bit signed float";
break;
1556 case GL_RGBA: type =
"RGBA, each channel 8-bit unsigned integer";
break;
1557 case GL_RGBA16F_ARB: type =
"RGBA, each channel 16-bit signed float";
break;
1558 case GL_RGBA32F_ARB: type =
"RGBA, each channel 32-bit signed float";
break;
1559 case GL_LUMINANCE8: type =
"intensity, 8-bit unsigned integer";
break;
1560 case GL_LUMINANCE16F_ARB: type =
"intensity, 16-bit signed float";
break;
1561 case GL_LUMINANCE32F_ARB: type =
"intensity, 32-bit signed float";
break;
1562 case GL_LUMINANCE8_ALPHA8: type =
"intensity+alpha, each channel 8-bit unsigned integer";
break;
1563 case GL_LUMINANCE_ALPHA16F_ARB: type =
"intensity+alpha, each channel 16-bit signed float";
break;
1564 case GL_LUMINANCE_ALPHA32F_ARB: type =
"intensity+alpha, each channel 32-bit signed float";
break;
1565 case GL_DEPTH_COMPONENT: type =
"intensity, 16-bit signed float";
break;
1566 default: type =
"(unknown)";
1572 char *summary =
VuoText_format(
"<div>%luĂ—%lu pixels @ %gx</div>\n<div>%s</div>\n<div>OpenGL: %s, %s, ID %u</div>",
1573 value->pixelsWide, value->pixelsHigh,
1578 value->glTextureName);
1580 free(internalformat);