20 #include <CoreServices/CoreServices.h>
22 #include <OpenGL/CGLMacro.h>
24 #define glGenVertexArrays glGenVertexArraysAPPLE
25 #define glBindVertexArray glBindVertexArrayAPPLE
26 #define glDeleteVertexArrays glDeleteVertexArraysAPPLE
35 "title" :
"VuoSceneRenderer",
44 "VuoList_VuoSceneObject",
53 typedef std::pair<std::string, double> VuoProfileEntry;
54 static bool VuoProfileSort(
const VuoProfileEntry &first,
const VuoProfileEntry &second)
56 return first.second < second.second;
86 float modelviewMatrix[16];
96 unsigned int viewportWidth;
97 unsigned int viewportHeight;
98 float backingScaleFactor;
108 list<VuoSceneRenderer_TreeRenderState> opaqueObjects;
109 list<VuoSceneRenderer_TreeRenderState> potentiallyTransparentObjects;
123 float projectionMatrix[16];
124 float cameraMatrixInverse[16];
130 float ambientBrightness;
134 GLint glContextRendererID;
146 GLenum vGL_CULL_FACE_MODE;
148 GLenum vGL_BLEND_SRC_RGB;
149 GLenum vGL_BLEND_DST_RGB;
150 GLenum vGL_BLEND_SRC_ALPHA;
151 GLenum vGL_BLEND_DST_ALPHA;
153 GLenum vGL_BLEND_EQUATION_RGB;
154 GLenum vGL_BLEND_EQUATION_ALPHA;
156 bool vGL_SAMPLE_ALPHA_TO_COVERAGE;
157 bool vGL_SAMPLE_ALPHA_TO_ONE;
162 GLuint renderDepthBuffer;
163 GLuint outputFramebuffer;
164 GLuint outputFramebuffer2;
167 std::list<VuoProfileEntry> profileTimes;
174 #define VuoSceneRenderer_setGL(cap, value) \
176 if (sceneRenderer->glState.v ## cap != value) \
182 sceneRenderer->glState.v ## cap = value; \
189 #define VuoSceneRenderer_setGLDepthMask(value) \
191 if (sceneRenderer->glState.vGL_DEPTH_MASK != value) \
193 glDepthMask(value); \
194 sceneRenderer->glState.vGL_DEPTH_MASK = value; \
201 #define VuoSceneRenderer_setGLFaceCulling(value) \
203 if (sceneRenderer->glState.vGL_CULL_FACE_MODE != value) \
206 sceneRenderer->glState.vGL_CULL_FACE_MODE = value; \
213 #define VuoSceneRenderer_setGLBlendFunction(srcRGB, dstRGB, srcAlpha, dstAlpha) \
215 if (sceneRenderer->glState.vGL_BLEND_SRC_RGB != srcRGB \
216 || sceneRenderer->glState.vGL_BLEND_DST_RGB != dstRGB \
217 || sceneRenderer->glState.vGL_BLEND_SRC_ALPHA != srcAlpha \
218 || sceneRenderer->glState.vGL_BLEND_DST_ALPHA != dstAlpha) \
220 glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); \
221 sceneRenderer->glState.vGL_BLEND_SRC_RGB = srcRGB; \
222 sceneRenderer->glState.vGL_BLEND_DST_RGB = dstRGB; \
223 sceneRenderer->glState.vGL_BLEND_SRC_ALPHA = srcAlpha; \
224 sceneRenderer->glState.vGL_BLEND_DST_ALPHA = dstAlpha; \
231 #define VuoSceneRenderer_setGLBlendEquation(modeRGB, modeAlpha) \
233 if (sceneRenderer->glState.vGL_BLEND_EQUATION_RGB != modeRGB \
234 || sceneRenderer->glState.vGL_BLEND_EQUATION_ALPHA != modeAlpha) \
236 glBlendEquationSeparate(modeRGB, modeAlpha); \
237 sceneRenderer->glState.vGL_BLEND_EQUATION_RGB = modeRGB; \
238 sceneRenderer->glState.vGL_BLEND_EQUATION_ALPHA = modeAlpha; \
247 #include "pro/VuoSceneRendererPro.h"
265 sceneRenderer->sharedTextOverrideShader = NULL;
267 sceneRenderer->cameraName = NULL;
270 sceneRenderer->backingScaleFactor = backingScaleFactor;
271 sceneRenderer->viewportWidth = 0;
272 sceneRenderer->viewportHeight = 0;
277 sceneRenderer->vignetteShader = NULL;
278 sceneRenderer->vignetteQuad =
nullptr;
280 VuoSceneRendererPro_init(sceneRenderer, cgl_ctx);
283 glGenRenderbuffersEXT(1, &sceneRenderer->renderBuffer);
284 glGenRenderbuffersEXT(1, &sceneRenderer->renderDepthBuffer);
285 glGenFramebuffers(1, &sceneRenderer->outputFramebuffer);
286 glGenFramebuffers(1, &sceneRenderer->outputFramebuffer2);
288 #pragma clang diagnostic push
289 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
290 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &sceneRenderer->glContextRendererID);
291 #pragma clang diagnostic pop
312 sceneRenderer->camera = camera;
316 if (sceneRenderer->cameraName && strlen(sceneRenderer->cameraName) != 0)
322 sceneRenderer->camera = camera;
330 sceneRenderer->camera = camera;
347 sceneRenderer->viewportWidth = width;
348 sceneRenderer->viewportHeight = height;
367 float aspectRatio = (float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight;
369 if (type == VuoSceneObjectSubType_PerspectiveCamera)
386 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
392 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
395 else if (type == VuoSceneObjectSubType_StereoCamera)
399 float top = cameraDistanceMin * tanf(halfFieldOfView);
400 float right = aspectRatio * top;
402 if (!sceneRenderer->useLeftCamera)
403 frustumshift *= -1.f;
420 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
424 sceneRenderer->
projectionMatrix[12] = (sceneRenderer->useLeftCamera ? 1.f : -1.f) * cameraIntraocularDistance / 2.f;
426 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
429 else if (type == VuoSceneObjectSubType_OrthographicCamera)
432 float halfWidth = cameraWidth / 2.f;
447 sceneRenderer->
projectionMatrix[10] = -2.f / (cameraDistanceMax - cameraDistanceMin);
453 sceneRenderer->
projectionMatrix[14] = -(cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMax - cameraDistanceMin);
456 else if (type == VuoSceneObjectSubType_FisheyeCamera)
460 VuoSceneRendererPro_generateFisheyeProjectionMatrix(sceneRenderer, sceneRenderer->camera, aspectRatio);
470 float cameraMatrix[16];
473 float invertedCameraMatrix[16];
488 *(address++) =
'0' + i;
492 *(address++) =
'0' + (i - 10);
495 strcpy(address, suffix);
506 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
509 VUserLog(
"Error: Vertex attrib array isn't enabled.");
513 unsigned int vertexCount, combinedBuffer, elementCount;
514 VuoMesh_getGPUBuffers(mesh, &vertexCount, &combinedBuffer,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
517 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vaovbo);
518 if (vaovbo != (GLint)combinedBuffer)
519 VUserLog(
"Error: GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING (%d) doesn't match submesh's VBO (%d).", vaovbo, combinedBuffer);
521 GLint vertexBufferBound = -1;
522 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertexBufferBound);
523 if (vertexBufferBound)
524 VUserLog(
"Error: GL_ARRAY_BUFFER_BINDING is %d (it should probably be 0, since we're using a VAO).", vertexBufferBound);
526 GLint elementBufferBound = -1;
527 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementBufferBound);
528 if (elementCount && !elementBufferBound)
529 VUserLog(
"Error: GL_ELEMENT_ARRAY_BUFFER_BINDING is 0 (it should be nonzero, since we're trying to draw elements).");
531 GLint combinedBufferSize = -1;
532 glBindBuffer(GL_ARRAY_BUFFER, combinedBuffer);
533 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &combinedBufferSize);
534 glBindBuffer(GL_ARRAY_BUFFER, 0);
535 if (combinedBufferSize < 4)
536 VUserLog(
"Error: combinedBuffer is unrealistically small (%d bytes).", combinedBufferSize);
538 GLint attribStride = -1;
539 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attribStride);
541 GLint attribComponents = -1;
542 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attribComponents);
544 GLint attribType = -1;
545 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attribType);
547 void *attribBase = (
void *)0;
548 glGetVertexAttribPointerv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attribBase);
550 unsigned int bytesPerComponent;
551 if (attribType == GL_UNSIGNED_INT)
552 bytesPerComponent = 1;
553 else if (attribType == GL_FLOAT)
554 bytesPerComponent = 4;
561 unsigned int minIndex = 0;
562 unsigned int maxIndex = 0;
566 if (elementBufferSize != elementCount *
sizeof(
unsigned int))
567 VUserLog(
"Error: elementBufferSize doesn't match elementCount.");
569 unsigned int *b = (
unsigned int *)malloc(elementBufferSize);
570 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, elementBufferSize, b);
572 for (
unsigned int i = 0; i < elementCount; ++i)
583 maxIndex = vertexCount - 1;
585 long startWithinVBO = (long)attribBase + (
unsigned int)attribStride * minIndex;
586 long endWithinVBO = (long)attribBase +(
unsigned int) attribStride * maxIndex + (
unsigned int)attribComponents * bytesPerComponent;
588 if (startWithinVBO < 0)
590 if (endWithinVBO < 0)
592 if (startWithinVBO > endWithinVBO)
594 if (endWithinVBO > combinedBufferSize)
595 VUserLog(
"Error: end > combinedBufferSize");
627 float verticalScale = 1.;
628 float rotationZ = 0.;
637 font.pointSize *= transform.scale.x;
638 wrapWidth *= transform.scale.x;
639 verticalScale = transform.scale.y / transform.scale.x;
643 VuoPoint2d corners[4];
646 VuoPoint2d anchorOffset =
VuoSceneText_getAnchorOffset(so, verticalScale, rotationZ, wrapWidth, sceneRenderer->viewportWidth, sceneRenderer->backingScaleFactor);
647 modelviewMatrix[12] += anchorOffset.x;
648 modelviewMatrix[13] += anchorOffset.y;
658 if (isRealSize && !image)
661 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
664 GLuint timeElapsedQuery;
665 glGenQueries(1, &timeElapsedQuery);
666 glBeginQuery(GL_TIME_ELAPSED_EXT, timeElapsedQuery);
669 GLint positionAttribute = -1;
672 VDebugLog(
"Error: Couldn't fetch the 'position' attribute, needed to check data bounds.");
678 VUserLog(
"Shader activation failed.");
684 glUniformMatrix4fv(projectionMatrixUniform, 1, GL_FALSE, projectionMatrix);
687 if (useFisheyeProjectionUniform != -1)
688 glUniform1i(useFisheyeProjectionUniform,
VuoSceneObject_getType(sceneRenderer->camera) == VuoSceneObjectSubType_FisheyeCamera);
694 float billboardMatrix[16];
697 VuoPoint2d mesh0 = (VuoPoint2d){ positions[0], positions[1] };
698 VuoTransform_getBillboardMatrix(image->pixelsWide, image->pixelsHigh, image->scaleFactor,
VuoSceneObject_shouldPreservePhysicalSize(so), modelviewMatrix[12], modelviewMatrix[13], sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, sceneRenderer->backingScaleFactor, mesh0, billboardMatrix);
699 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, billboardMatrix);
702 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, modelviewMatrix);
705 if (cameraMatrixInverseUniform != -1)
706 glUniformMatrix4fv(cameraMatrixInverseUniform, 1, GL_FALSE, sceneRenderer->
cameraMatrixInverse);
709 if (cameraPositionUniform != -1)
712 glUniform3f(cameraPositionUniform, p.x, p.y, p.z);
716 if (aspectRatioUniform != -1)
717 glUniform1f(aspectRatioUniform, (
float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight);
720 if (viewportSizeUniform != -1)
721 glUniform2f(viewportSizeUniform, (
float)sceneRenderer->viewportWidth, (
float)sceneRenderer->viewportHeight);
724 if (ambientColorUniform != -1)
727 glUniform4f(ambientColorUniform,
728 pow(sceneRenderer->ambientColor.r, 2.2) * sceneRenderer->ambientColor.a,
729 pow(sceneRenderer->ambientColor.g, 2.2) * sceneRenderer->ambientColor.a,
730 pow(sceneRenderer->ambientColor.b, 2.2) * sceneRenderer->ambientColor.a,
731 sceneRenderer->ambientColor.a);
733 if (ambientBrightnessUniform != -1)
734 glUniform1f(ambientBrightnessUniform, pow(sceneRenderer->ambientBrightness, 2.2));
736 size_t uniformSize = 27;
737 char uniformName[uniformSize];
741 if (pointLightCountUniform != -1)
743 glUniform1i(pointLightCountUniform, pointLightCount);
745 strlcpy(uniformName,
"pointLights[", uniformSize);
746 const int prefixLength = 12;
748 for (
int i=1; i<=pointLightCount; ++i)
757 glUniform4f(colorUniform,
770 glUniform3f(positionUniform, p.x, p.y, p.z);
784 if (spotLightCountUniform != -1)
786 glUniform1i(spotLightCountUniform, spotLightCount);
788 strlcpy(uniformName,
"spotLights[", uniformSize);
789 const int prefixLength = 11;
791 for (
int i=1; i<=spotLightCount; ++i)
800 glUniform4f(colorUniform,
813 glUniform3f(positionUniform, p.x, p.y, p.z);
818 glUniform3f(directionUniform, direction.x, direction.y, direction.z);
882 unsigned int vertexCount, elementCount;
883 void *textureCoordinateOffset, *colorOffset;
884 VuoMesh_getGPUBuffers(mesh, &vertexCount,
nullptr,
nullptr, &textureCoordinateOffset, &colorOffset, &elementCount,
nullptr);
887 if (hasTextureCoordinatesUniform != -1)
888 glUniform1i(hasTextureCoordinatesUniform, textureCoordinateOffset != NULL);
891 if (hasVertexColorsUniform != -1)
892 glUniform1i(hasVertexColorsUniform, colorOffset !=
nullptr);
895 if (primitiveHalfSizeUniform != -1)
899 bool enableCulling = faceCullingGL != GL_NONE && !shader->isTransparent;
912 glDrawElements(mode, completeInputElementCount, GL_UNSIGNED_INT, (
void*)0);
913 else if (vertexCount)
914 glDrawArrays(mode, 0, completeInputElementCount);
922 glEndQuery(GL_TIME_ELAPSED_EXT);
924 glGetQueryObjectuiv(timeElapsedQuery, GL_QUERY_RESULT, &nanoseconds);
925 seconds = ((double)nanoseconds) / NSEC_PER_SEC;
926 glDeleteQueries(1, &timeElapsedQuery);
928 std::string description = so.name ? std::string(so.name) :
"no name";
929 description += std::string(
" (") + shader->name +
")";
930 sceneRenderer->profileTimes.push_back(make_pair(description, seconds));
945 for (
auto currentState : renderList)
1003 VLog(
"Render lists:");
1005 for (
auto currentState : sceneRenderer->opaqueObjects)
1007 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
1008 currentState.modelviewMatrix[12],
1009 currentState.modelviewMatrix[13],
1010 currentState.modelviewMatrix[14],
1011 currentState.so->shader ? currentState.so->shader->name : NULL
1014 VLog(
" Potentially Transparent:");
1015 for (
auto currentState : sceneRenderer->potentiallyTransparentObjects)
1017 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
1018 currentState.modelviewMatrix[12],
1019 currentState.modelviewMatrix[13],
1020 currentState.modelviewMatrix[14],
1021 currentState.so->shader->name
1029 bzero(&sceneRenderer->glState,
sizeof(sceneRenderer->glState));
1030 sceneRenderer->glState.vGL_DEPTH_MASK =
true;
1031 sceneRenderer->glState.vGL_DEPTH_TEST =
false;
1032 sceneRenderer->glState.vGL_CULL_FACE =
true;
1033 sceneRenderer->glState.vGL_CULL_FACE_MODE = GL_BACK;
1034 sceneRenderer->glState.vGL_BLEND_SRC_RGB = GL_ONE;
1035 sceneRenderer->glState.vGL_BLEND_DST_RGB = GL_ONE_MINUS_SRC_ALPHA;
1036 sceneRenderer->glState.vGL_BLEND_SRC_ALPHA = GL_ONE;
1037 sceneRenderer->glState.vGL_BLEND_DST_ALPHA = GL_ONE_MINUS_SRC_ALPHA;
1038 sceneRenderer->glState.vGL_BLEND_EQUATION_RGB = GL_FUNC_ADD;
1039 sceneRenderer->glState.vGL_BLEND_EQUATION_ALPHA = GL_FUNC_ADD;
1040 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_COVERAGE =
false;
1041 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_ONE =
false;
1047 if (!sceneRenderer->potentiallyTransparentObjects.empty())
1066 VuoSceneRendererPro_drawVignette(sceneRenderer, cgl_ctx);
1071 VLog(
"Object render time (percent of a 60 Hz frame)");
1072 double totalPercent = 0;
1073 sceneRenderer->profileTimes.sort(VuoProfileSort);
1074 for (std::list<VuoProfileEntry>::iterator i = sceneRenderer->profileTimes.begin(); i != sceneRenderer->profileTimes.end(); ++i)
1076 double objectPercent = i->second / (1./60.) * 100.;
1077 VLog(
" %6.2f %s", objectPercent, i->first.c_str());
1078 totalPercent += objectPercent;
1080 VLog(
" ------ -----");
1081 VLog(
" %6.2f total", totalPercent);
1082 sceneRenderer->profileTimes.clear();
1085 glFlushRenderAPPLE();
1090 #pragma clang diagnostic push
1091 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1092 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &rendererID);
1093 #pragma clang diagnostic pop
1094 if (rendererID != sceneRenderer->glContextRendererID)
1097 sceneRenderer->glContextRendererID = rendererID;
1334 if (!sceneRenderer->sharedTextOverrideShader)
1337 VuoRetain(sceneRenderer->sharedTextOverrideShader);
1357 VuoSceneRendererMeshShaderVAOs::iterator i = sceneRenderer->
meshShaderItems.find(meshShader);
1360 soi->
vao = i->second;
1367 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1371 GLint positionAttribute, normalAttribute, textureCoordinateAttribute, colorAttribute;
1373 VUserLog(
"Error: Couldn't fetch the shader's attribute locations.");
1375 unsigned int combinedBuffer, elementCount, elementBuffer;
1376 void *normalOffset, *textureCoordinateOffset, *colorOffset;
1377 VuoMesh_getGPUBuffers(mesh,
nullptr, &combinedBuffer, &normalOffset, &textureCoordinateOffset, &colorOffset, &elementCount, &elementBuffer);
1388 glBindBuffer(GL_ARRAY_BUFFER, combinedBuffer);
1393 int stride =
sizeof(float) * 3;
1394 glEnableVertexAttribArray((GLuint)positionAttribute);
1395 glVertexAttribPointer((GLuint)positionAttribute, 3 , GL_FLOAT, GL_FALSE, stride, (
void*)0);
1397 if (normalOffset && normalAttribute>=0)
1399 glEnableVertexAttribArray((GLuint)normalAttribute);
1400 glVertexAttribPointer((GLuint)normalAttribute, 3 , GL_FLOAT, GL_FALSE, stride, normalOffset);
1403 if (textureCoordinateOffset && textureCoordinateAttribute>=0)
1405 glEnableVertexAttribArray((GLuint)textureCoordinateAttribute);
1406 glVertexAttribPointer((GLuint)textureCoordinateAttribute, 2 , GL_FLOAT, GL_FALSE,
sizeof(
float) * 2, textureCoordinateOffset);
1409 if (colorOffset && colorAttribute >= 0)
1411 glEnableVertexAttribArray((GLuint)colorAttribute);
1412 glVertexAttribPointer((GLuint)colorAttribute, 4 , GL_FLOAT, GL_FALSE,
sizeof(
float) * 4, colorOffset);
1417 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
1422 soi->
vao = vertexArray;
1424 glBindBuffer(GL_ARRAY_BUFFER, 0);
1446 list<VuoSceneRenderer_TreeRenderState> objects(1, rootState);
1447 while (!objects.empty())
1450 objects.pop_front();
1452 float localModelviewMatrix[16];
1454 float compositeModelviewMatrix[16];
1464 sceneRenderer->opaqueObjects.push_back(currentState);
1466 sceneRenderer->potentiallyTransparentObjects.push_back(currentState);
1469 sceneRenderer->opaqueObjects.push_back(currentState);
1478 childState.so = childObjects[i];
1480 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
1481 objects.push_front(childState);
1485 delete currentState.soi;
1512 for (
auto object : sceneRenderer->opaqueObjects)
1514 if (
object.soi->overrideShader)
1518 sceneRenderer->opaqueObjects.clear();
1520 for (
auto object : sceneRenderer->potentiallyTransparentObjects)
1522 if (
object.soi->overrideShader)
1526 sceneRenderer->potentiallyTransparentObjects.clear();
1534 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1597 if (sceneRenderer->cameraName)
1600 sceneRenderer->cameraName = cameraName;
1603 sceneRenderer->useLeftCamera = useLeftCamera;
1634 if (sceneRenderer->sharedTextOverrideShader)
1635 VuoRelease(sceneRenderer->sharedTextOverrideShader);
1637 if (sceneRenderer->cameraName)
1647 glDeleteRenderbuffersEXT(1, &sceneRenderer->renderBuffer);
1648 glDeleteRenderbuffersEXT(1, &sceneRenderer->renderDepthBuffer);
1649 glDeleteFramebuffers(1, &sceneRenderer->outputFramebuffer);
1650 glDeleteFramebuffers(1, &sceneRenderer->outputFramebuffer2);
1656 delete sceneRenderer;
1666 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1668 static bool force2DDepth =
true;
1669 static dispatch_once_t once = 0;
1670 dispatch_once(&once, ^{
1672 Boolean overridden =
false;
1673 force2DDepth = (int)CFPreferencesGetAppIntegerValue(CFSTR(
"force2DDepth"), CFSTR(
"org.vuo.Editor"), &overridden);
1683 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1684 if (strcmp(renderer,
"NVIDIA GeForce GT 650M OpenGL Engine") == 0
1685 || strcmp(renderer,
"NVIDIA GeForce 9400M OpenGL Engine") == 0)
1686 force2DDepth =
false;
1688 force2DDepth =
true;
1691 VDebugLog(
"force2DDepth = %d", force2DDepth);
1695 unsigned long requiredBytes = sceneRenderer->viewportWidth * sceneRenderer->viewportHeight * colorBytesPerPixel;
1696 if (outputDepthTexture)
1697 requiredBytes += sceneRenderer->viewportWidth * sceneRenderer->viewportHeight *
VuoGlTexture_getBytesPerPixel(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
1701 bool actuallyMultisampling = multisample > 1;
1704 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1705 if (strcmp(renderer,
"Intel HD Graphics 3000") == 0)
1710 requiredBytes += requiredBytes * multisample * fudge;
1713 if (maximumTextureBytes > 0 && requiredBytes > maximumTextureBytes)
1715 VUserLog(
"Not enough graphics memory for a %dx%d (%d bytes/pixel * %d sample) render%s. Requires %lu MB, have %lu MB.",
1716 sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1717 colorBytesPerPixel, multisample==0?1:multisample,
1718 outputDepthTexture ?
" with depth buffer" :
"",
1719 requiredBytes/1024/1024, maximumTextureBytes/1024/1024);
1725 if (!*outputTexture)
1726 *outputTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_BGRA, NULL);
1728 if (outputDepthTexture)
1729 *outputDepthTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_DEPTH_COMPONENT, NULL);
1731 if (!*outputTexture || (outputDepthTexture && !*outputDepthTexture))
1736 glBindFramebuffer(GL_FRAMEBUFFER, sceneRenderer->outputFramebuffer);
1740 if (actuallyMultisampling)
1742 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1744 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1745 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1747 if (outputDepthTexture)
1749 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1750 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1751 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1756 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1757 if (outputDepthTexture)
1758 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1765 if (invertDepthImage)
1769 glDepthFunc(GL_GREATER);
1775 glDepthFunc(GL_LESS);
1778 glViewport(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1779 glClearColor(0,0,0,0);
1780 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1787 if (actuallyMultisampling)
1789 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sceneRenderer->outputFramebuffer2);
1792 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1793 if (outputDepthTexture)
1794 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1796 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, sceneRenderer->outputFramebuffer);
1797 glReadBuffer(GL_COLOR_ATTACHMENT0);
1798 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1799 glBlitFramebufferEXT(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1800 0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1801 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1804 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1805 if (outputDepthTexture)
1806 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1809 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1813 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1814 if (outputDepthTexture)
1815 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1819 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1823 glFlushRenderAPPLE();
1843 __block GLuint texture = 0;
1844 __block GLuint depthTexture = 0;
1846 if (!
VuoSceneRenderer_renderInternal(sr, cgl_ctx, &texture, GL_TEXTURE_2D, imageGlInternalFormat, multisample, depthImage ? &depthTexture : NULL, invertDepthImage))
1854 *image =
VuoImage_make(texture, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1856 *depthImage =
VuoImage_make(depthTexture, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1872 __block GLuint texture = 0;
1873 __block GLuint depthTexture = 0;
1874 __block
bool renderSucceeded;
1877 vis =
VuoIoSurfacePool_use(cgl_ctx, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, &texture);
1878 renderSucceeded =
VuoSceneRenderer_renderInternal(sr, cgl_ctx, &texture, GL_TEXTURE_RECTANGLE_ARB, imageGlInternalFormat, multisample, includeDepthBuffer ? &depthTexture : NULL,
false);
1880 if (!renderSucceeded)
1886 if (includeDepthBuffer)
1888 VuoImage depthImage =
VuoImage_make(depthTexture, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);