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;
279 VuoSceneRendererPro_init(sceneRenderer, cgl_ctx);
282 glGenRenderbuffersEXT(1, &sceneRenderer->renderBuffer);
283 glGenRenderbuffersEXT(1, &sceneRenderer->renderDepthBuffer);
284 glGenFramebuffers(1, &sceneRenderer->outputFramebuffer);
285 glGenFramebuffers(1, &sceneRenderer->outputFramebuffer2);
287 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &sceneRenderer->glContextRendererID);
308 sceneRenderer->camera = camera;
312 if (sceneRenderer->cameraName && strlen(sceneRenderer->cameraName) != 0)
318 sceneRenderer->camera = camera;
326 sceneRenderer->camera = camera;
343 sceneRenderer->viewportWidth = width;
344 sceneRenderer->viewportHeight = height;
363 float aspectRatio = (float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight;
364 if (sceneRenderer->camera.type == VuoSceneObjectSubType_PerspectiveCamera)
366 float halfFieldOfView = (sceneRenderer->camera.
cameraFieldOfView * (float)M_PI / 180.f) / 2.f;
381 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
387 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
390 else if (sceneRenderer->camera.type == VuoSceneObjectSubType_StereoCamera)
392 float halfFieldOfView = (sceneRenderer->camera.
cameraFieldOfView * (float)M_PI / 180.f) / 2.f;
393 float top = cameraDistanceMin * tanf(halfFieldOfView);
394 float right = aspectRatio * top;
396 if (!sceneRenderer->useLeftCamera)
397 frustumshift *= -1.f;
414 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
420 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
423 else if (sceneRenderer->camera.type == VuoSceneObjectSubType_OrthographicCamera)
425 float halfWidth = sceneRenderer->camera.
cameraWidth / 2.f;
440 sceneRenderer->
projectionMatrix[10] = -2.f / (cameraDistanceMax - cameraDistanceMin);
446 sceneRenderer->
projectionMatrix[14] = -(cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMax - cameraDistanceMin);
449 else if (sceneRenderer->camera.type == VuoSceneObjectSubType_FisheyeCamera)
453 VuoSceneRendererPro_generateFisheyeProjectionMatrix(sceneRenderer, sceneRenderer->camera, aspectRatio);
457 VUserLog(
"Unknown type %d", sceneRenderer->camera.type);
463 float cameraMatrix[16];
466 float invertedCameraMatrix[16];
481 *(address++) =
'0' + i;
485 *(address++) =
'0' + (i - 10);
488 strcpy(address, suffix);
499 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
502 VUserLog(
"Error: Vertex attrib array isn't enabled.");
507 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vaovbo);
508 if (vaovbo != (GLint)submesh.
glUpload.combinedBuffer)
509 VUserLog(
"Error: GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING (%d) doesn't match submesh's VBO (%d).", vaovbo, submesh.
glUpload.combinedBuffer);
511 GLint vertexBufferBound = -1;
512 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertexBufferBound);
513 if (vertexBufferBound)
514 VUserLog(
"Error: GL_ARRAY_BUFFER_BINDING is %d (it should probably be 0, since we're using a VAO).", vertexBufferBound);
516 GLint elementBufferBound = -1;
517 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementBufferBound);
519 VUserLog(
"Error: GL_ELEMENT_ARRAY_BUFFER_BINDING is 0 (it should be nonzero, since we're trying to draw elements).");
521 GLint combinedBufferSize = -1;
522 glBindBuffer(GL_ARRAY_BUFFER, submesh.
glUpload.combinedBuffer);
523 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &combinedBufferSize);
524 glBindBuffer(GL_ARRAY_BUFFER, 0);
525 if (combinedBufferSize < 4)
526 VUserLog(
"Error: combinedBuffer is unrealistically small (%d bytes).", combinedBufferSize);
528 GLint attribStride = -1;
529 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attribStride);
531 GLint attribComponents = -1;
532 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attribComponents);
534 GLint attribType = -1;
535 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attribType);
537 void *attribBase = (
void *)0;
538 glGetVertexAttribPointerv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attribBase);
540 unsigned int bytesPerComponent;
541 if (attribType == GL_UNSIGNED_INT)
542 bytesPerComponent = 1;
543 else if (attribType == GL_FLOAT)
544 bytesPerComponent = 4;
551 unsigned int minIndex = 0;
552 unsigned int maxIndex = 0;
556 VUserLog(
"Error: elementBufferSize doesn't match elementCount.");
558 unsigned int *b = (
unsigned int *)malloc(submesh.
glUpload.elementBufferSize);
559 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, submesh.
glUpload.elementBufferSize, b);
574 long startWithinVBO = (long)attribBase + (
unsigned int)attribStride * minIndex;
575 long endWithinVBO = (long)attribBase +(
unsigned int) attribStride * maxIndex + (
unsigned int)attribComponents * bytesPerComponent;
577 if (startWithinVBO < 0)
579 if (endWithinVBO < 0)
581 if (startWithinVBO > endWithinVBO)
583 if (endWithinVBO > combinedBufferSize)
584 VUserLog(
"Error: end > combinedBufferSize");
606 if (so.type == VuoSceneObjectSubType_Text && so.text && so.text[0] != 0)
612 float verticalScale = 1.;
613 float rotationZ = 0.;
614 float wrapWidth = so.wrapWidth;
615 if (so.scaleWithScene)
621 so.font.pointSize *= transform.scale.x;
622 wrapWidth *= transform.scale.x;
623 verticalScale = transform.scale.y / transform.scale.x;
627 VuoPoint2d corners[4];
628 VuoImage textImage =
VuoImage_makeText(so.text, so.font, sceneRenderer->backingScaleFactor, verticalScale, rotationZ, wrapWidth, corners);
630 VuoPoint2d anchorOffset =
VuoSceneText_getAnchorOffset(so, verticalScale, rotationZ, wrapWidth, sceneRenderer->viewportWidth, sceneRenderer->backingScaleFactor);
631 modelviewMatrix[12] += anchorOffset.x;
632 modelviewMatrix[13] += anchorOffset.y;
645 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
648 GLuint timeElapsedQuery;
649 glGenQueries(1, &timeElapsedQuery);
650 glBeginQuery(GL_TIME_ELAPSED_EXT, timeElapsedQuery);
653 GLint positionAttribute = -1;
656 VDebugLog(
"Error: Couldn't fetch the 'position' attribute, needed to check data bounds.");
663 VUserLog(
"Shader activation failed.");
669 glUniformMatrix4fv(projectionMatrixUniform, 1, GL_FALSE, projectionMatrix);
672 if (useFisheyeProjectionUniform != -1)
673 glUniform1i(useFisheyeProjectionUniform, sceneRenderer->camera.type == VuoSceneObjectSubType_FisheyeCamera);
679 float billboardMatrix[16];
681 VuoTransform_getBillboardMatrix(image->
pixelsWide, image->
pixelsHigh, image->
scaleFactor, so.
preservePhysicalSize, modelviewMatrix[12], modelviewMatrix[13], sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, sceneRenderer->backingScaleFactor, mesh0, billboardMatrix);
682 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, billboardMatrix);
685 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, modelviewMatrix);
688 if (cameraMatrixInverseUniform != -1)
689 glUniformMatrix4fv(cameraMatrixInverseUniform, 1, GL_FALSE, sceneRenderer->
cameraMatrixInverse);
692 if (cameraPositionUniform != -1)
693 glUniform3f(cameraPositionUniform, sceneRenderer->camera.transform.translation.x, sceneRenderer->camera.transform.translation.y, sceneRenderer->camera.transform.translation.z);
696 if (aspectRatioUniform != -1)
697 glUniform1f(aspectRatioUniform, (
float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight);
700 if (viewportSizeUniform != -1)
701 glUniform2f(viewportSizeUniform, (
float)sceneRenderer->viewportWidth, (
float)sceneRenderer->viewportHeight);
704 if (ambientColorUniform != -1)
707 glUniform4f(ambientColorUniform,
708 pow(sceneRenderer->ambientColor.r, 2.2) * sceneRenderer->ambientColor.a,
709 pow(sceneRenderer->ambientColor.g, 2.2) * sceneRenderer->ambientColor.a,
710 pow(sceneRenderer->ambientColor.b, 2.2) * sceneRenderer->ambientColor.a,
711 sceneRenderer->ambientColor.a);
713 if (ambientBrightnessUniform != -1)
714 glUniform1f(ambientBrightnessUniform, pow(sceneRenderer->ambientBrightness, 2.2));
716 size_t uniformSize = 27;
717 char uniformName[uniformSize];
721 if (pointLightCountUniform != -1)
723 glUniform1i(pointLightCountUniform, pointLightCount);
725 strlcpy(uniformName,
"pointLights[", uniformSize);
726 const int prefixLength = 12;
728 for (
int i=1; i<=pointLightCount; ++i)
736 glUniform4f(colorUniform,
737 pow(pointLight.lightColor.r, 2.2) * pointLight.lightColor.a,
738 pow(pointLight.lightColor.g, 2.2) * pointLight.lightColor.a,
739 pow(pointLight.lightColor.b, 2.2) * pointLight.lightColor.a,
740 pointLight.lightColor.a);
744 glUniform1f(brightnessUniform, pow(pointLight.lightBrightness, 2.2));
748 glUniform3f(positionUniform, pointLight.transform.translation.x, pointLight.transform.translation.y, pointLight.transform.translation.z);
752 glUniform1f(rangeUniform, pointLight.
lightRange);
762 if (spotLightCountUniform != -1)
764 glUniform1i(spotLightCountUniform, spotLightCount);
766 strlcpy(uniformName,
"spotLights[", uniformSize);
767 const int prefixLength = 11;
769 for (
int i=1; i<=spotLightCount; ++i)
777 glUniform4f(colorUniform,
778 pow(spotLight.lightColor.r, 2.2) * spotLight.lightColor.a,
779 pow(spotLight.lightColor.g, 2.2) * spotLight.lightColor.a,
780 pow(spotLight.lightColor.b, 2.2) * spotLight.lightColor.a,
781 spotLight.lightColor.a);
785 glUniform1f(brightnessUniform, pow(spotLight.lightBrightness, 2.2));
789 glUniform3f(positionUniform, spotLight.transform.translation.x, spotLight.transform.translation.y, spotLight.transform.translation.z);
794 glUniform3f(directionUniform, direction.x, direction.y, direction.z);
798 glUniform1f(coneUniform, spotLight.
lightCone);
802 glUniform1f(rangeUniform, spotLight.
lightRange);
859 if (hasTextureCoordinatesUniform != -1)
860 glUniform1i(hasTextureCoordinatesUniform, submesh.
glUpload.textureCoordinateOffset != NULL);
863 if (primitiveHalfSizeUniform != -1)
864 glUniform1f(primitiveHalfSizeUniform, submesh.
primitiveSize/2);
879 glDrawElements(mode, completeInputElementCount, GL_UNSIGNED_INT, (
void*)0);
881 glDrawArrays(mode, 0, completeInputElementCount);
889 glEndQuery(GL_TIME_ELAPSED_EXT);
891 glGetQueryObjectuiv(timeElapsedQuery, GL_QUERY_RESULT, &nanoseconds);
892 seconds = ((double)nanoseconds) / NSEC_PER_SEC;
893 glDeleteQueries(1, &timeElapsedQuery);
895 std::string description = so.name ? std::string(so.name) :
"no name";
896 description += std::string(
" (") + so.shader->
name +
")";
897 sceneRenderer->profileTimes.push_back(make_pair(description, seconds));
912 for (
auto currentState : renderList)
947 if (sceneRenderer->rootSceneObjectValid)
949 VuoSceneRenderer_cleanupRenderLists(sceneRenderer);
950 VuoSceneRenderer_cleanupMeshShaderItems(sceneRenderer, cgl_ctx);
951 VuoSceneObject_release(sceneRenderer->rootSceneObject);
952 VuoRelease(sceneRenderer->pointLights);
953 VuoRelease(sceneRenderer->spotLights);
972 VLog(
"Render lists:");
974 for (
auto currentState : sceneRenderer->opaqueObjects)
976 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
977 currentState.modelviewMatrix[12],
978 currentState.modelviewMatrix[13],
979 currentState.modelviewMatrix[14],
980 currentState.so->shader ? currentState.so->shader->name : NULL
983 VLog(
" Potentially Transparent:");
984 for (
auto currentState : sceneRenderer->potentiallyTransparentObjects)
986 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
987 currentState.modelviewMatrix[12],
988 currentState.modelviewMatrix[13],
989 currentState.modelviewMatrix[14],
990 currentState.so->shader->name
998 bzero(&sceneRenderer->glState,
sizeof(sceneRenderer->glState));
999 sceneRenderer->glState.vGL_DEPTH_MASK =
true;
1000 sceneRenderer->glState.vGL_DEPTH_TEST =
false;
1001 sceneRenderer->glState.vGL_CULL_FACE =
true;
1002 sceneRenderer->glState.vGL_CULL_FACE_MODE = GL_BACK;
1003 sceneRenderer->glState.vGL_BLEND_SRC_RGB = GL_ONE;
1004 sceneRenderer->glState.vGL_BLEND_DST_RGB = GL_ONE_MINUS_SRC_ALPHA;
1005 sceneRenderer->glState.vGL_BLEND_SRC_ALPHA = GL_ONE;
1006 sceneRenderer->glState.vGL_BLEND_DST_ALPHA = GL_ONE_MINUS_SRC_ALPHA;
1007 sceneRenderer->glState.vGL_BLEND_EQUATION_RGB = GL_FUNC_ADD;
1008 sceneRenderer->glState.vGL_BLEND_EQUATION_ALPHA = GL_FUNC_ADD;
1009 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_COVERAGE =
false;
1010 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_ONE =
false;
1016 if (!sceneRenderer->potentiallyTransparentObjects.empty())
1034 if (sceneRenderer->camera.type == VuoSceneObjectSubType_FisheyeCamera)
1035 VuoSceneRendererPro_drawVignette(sceneRenderer, cgl_ctx);
1040 VLog(
"Object render time (percent of a 60 Hz frame)");
1041 double totalPercent = 0;
1042 sceneRenderer->profileTimes.sort(VuoProfileSort);
1043 for (std::list<VuoProfileEntry>::iterator i = sceneRenderer->profileTimes.begin(); i != sceneRenderer->profileTimes.end(); ++i)
1045 double objectPercent = i->second / (1./60.) * 100.;
1046 VLog(
" %6.2f %s", objectPercent, i->first.c_str());
1047 totalPercent += objectPercent;
1049 VLog(
" ------ -----");
1050 VLog(
" %6.2f total", totalPercent);
1051 sceneRenderer->profileTimes.clear();
1054 glFlushRenderAPPLE();
1059 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &rendererID);
1060 if (rendererID != sceneRenderer->glContextRendererID)
1063 sceneRenderer->glContextRendererID = rendererID;
1299 if (so->type == VuoSceneObjectSubType_Text && so->text && so->text[0] != 0)
1302 if (!sceneRenderer->sharedTextOverrideShader)
1305 VuoRetain(sceneRenderer->sharedTextOverrideShader);
1323 VuoSceneRendererMeshShaderVAOs::iterator i = sceneRenderer->
meshShaderItems.find(meshShader);
1326 soi->
vao = i->second;
1333 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1337 GLint positionAttribute, normalAttribute, tangentAttribute, bitangentAttribute, textureCoordinateAttribute;
1339 VUserLog(
"Error: Couldn't fetch the shader's attribute locations.");
1358 glEnableVertexAttribArray((GLuint)positionAttribute);
1359 glVertexAttribPointer((GLuint)positionAttribute, 4 , GL_FLOAT, GL_FALSE, stride, (
void*)0);
1361 if (meshItem.
glUpload.normalOffset && normalAttribute>=0)
1363 glEnableVertexAttribArray((GLuint)normalAttribute);
1364 glVertexAttribPointer((GLuint)normalAttribute, 4 , GL_FLOAT, GL_FALSE, stride, so->mesh->
submeshes[0].
glUpload.normalOffset);
1367 if (meshItem.
glUpload.tangentOffset && tangentAttribute>=0)
1369 glEnableVertexAttribArray((GLuint)tangentAttribute);
1370 glVertexAttribPointer((GLuint)tangentAttribute, 4 , GL_FLOAT, GL_FALSE, stride, so->mesh->
submeshes[0].
glUpload.tangentOffset);
1373 if (meshItem.
glUpload.bitangentOffset && bitangentAttribute>=0)
1375 glEnableVertexAttribArray((GLuint)bitangentAttribute);
1376 glVertexAttribPointer((GLuint)bitangentAttribute, 4 , GL_FLOAT, GL_FALSE, stride, so->mesh->
submeshes[0].
glUpload.bitangentOffset);
1379 if (meshItem.
glUpload.textureCoordinateOffset && textureCoordinateAttribute>=0)
1381 glEnableVertexAttribArray((GLuint)textureCoordinateAttribute);
1382 glVertexAttribPointer((GLuint)textureCoordinateAttribute, 4 , GL_FLOAT, GL_FALSE, stride, so->mesh->
submeshes[0].
glUpload.textureCoordinateOffset);
1388 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, so->mesh->
submeshes[0].
glUpload.elementBuffer);
1393 soi->
vao = vertexArray;
1395 glBindBuffer(GL_ARRAY_BUFFER, 0);
1417 list<VuoSceneRenderer_TreeRenderState> objects(1, rootState);
1418 while (!objects.empty())
1421 objects.pop_front();
1423 float localModelviewMatrix[16];
1425 float compositeModelviewMatrix[16];
1435 sceneRenderer->opaqueObjects.push_back(currentState);
1437 sceneRenderer->potentiallyTransparentObjects.push_back(currentState);
1440 sceneRenderer->opaqueObjects.push_back(currentState);
1449 childState.so = &(childObjects[i]);
1451 memcpy(childState.modelviewMatrix, compositeModelviewMatrix,
sizeof(
float[16]));
1452 objects.push_front(childState);
1456 delete currentState.soi;
1483 for (
auto object : sceneRenderer->opaqueObjects)
1485 if (
object.soi->overrideShader)
1489 sceneRenderer->opaqueObjects.clear();
1491 for (
auto object : sceneRenderer->potentiallyTransparentObjects)
1493 if (
object.soi->overrideShader)
1497 sceneRenderer->potentiallyTransparentObjects.clear();
1505 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1568 if (sceneRenderer->cameraName)
1571 sceneRenderer->cameraName = cameraName;
1574 sceneRenderer->useLeftCamera = useLeftCamera;
1605 if (sceneRenderer->sharedTextOverrideShader)
1606 VuoRelease(sceneRenderer->sharedTextOverrideShader);
1608 if (sceneRenderer->cameraName)
1617 glDeleteRenderbuffersEXT(1, &sceneRenderer->renderBuffer);
1618 glDeleteRenderbuffersEXT(1, &sceneRenderer->renderDepthBuffer);
1619 glDeleteFramebuffers(1, &sceneRenderer->outputFramebuffer);
1620 glDeleteFramebuffers(1, &sceneRenderer->outputFramebuffer2);
1626 delete sceneRenderer;
1636 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1638 static bool force2DDepth =
true;
1639 static dispatch_once_t once = 0;
1640 dispatch_once(&once, ^{
1642 Boolean overridden =
false;
1643 force2DDepth = (int)CFPreferencesGetAppIntegerValue(CFSTR(
"force2DDepth"), CFSTR(
"org.vuo.Editor"), &overridden);
1653 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1654 if (strcmp(renderer,
"NVIDIA GeForce GT 650M OpenGL Engine") == 0
1655 || strcmp(renderer,
"NVIDIA GeForce 9400M OpenGL Engine") == 0)
1656 force2DDepth =
false;
1658 force2DDepth =
true;
1661 VDebugLog(
"force2DDepth = %d", force2DDepth);
1665 unsigned long requiredBytes = sceneRenderer->viewportWidth * sceneRenderer->viewportHeight * colorBytesPerPixel;
1666 if (outputDepthTexture)
1667 requiredBytes += sceneRenderer->viewportWidth * sceneRenderer->viewportHeight *
VuoGlTexture_getBytesPerPixel(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
1671 bool actuallyMultisampling = multisample > 1;
1674 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1675 if (strcmp(renderer,
"Intel HD Graphics 3000") == 0)
1680 requiredBytes += requiredBytes * multisample * fudge;
1683 if (maximumTextureBytes > 0 && requiredBytes > maximumTextureBytes)
1685 VUserLog(
"Not enough graphics memory for a %dx%d (%d bytes/pixel * %d sample) render%s. Requires %lu MB, have %lu MB.",
1686 sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1687 colorBytesPerPixel, multisample==0?1:multisample,
1688 outputDepthTexture ?
" with depth buffer" :
"",
1689 requiredBytes/1024/1024, maximumTextureBytes/1024/1024);
1695 if (!*outputTexture)
1696 *outputTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_BGRA, NULL);
1698 if (outputDepthTexture)
1699 *outputDepthTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_DEPTH_COMPONENT, NULL);
1701 if (!*outputTexture || (outputDepthTexture && !*outputDepthTexture))
1706 glBindFramebuffer(GL_FRAMEBUFFER, sceneRenderer->outputFramebuffer);
1710 if (actuallyMultisampling)
1712 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1714 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1715 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1717 if (outputDepthTexture)
1719 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1720 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1721 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1726 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1727 if (outputDepthTexture)
1728 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1735 if (invertDepthImage)
1739 glDepthFunc(GL_GREATER);
1745 glDepthFunc(GL_LESS);
1748 glViewport(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1749 glClearColor(0,0,0,0);
1750 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1757 if (actuallyMultisampling)
1759 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sceneRenderer->outputFramebuffer2);
1762 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1763 if (outputDepthTexture)
1764 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1766 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, sceneRenderer->outputFramebuffer);
1767 glReadBuffer(GL_COLOR_ATTACHMENT0);
1768 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1769 glBlitFramebufferEXT(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1770 0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1771 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1774 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1775 if (outputDepthTexture)
1776 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1779 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1783 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1784 if (outputDepthTexture)
1785 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1789 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1793 glFlushRenderAPPLE();
1813 __block GLuint texture = 0;
1814 __block GLuint depthTexture = 0;
1816 if (!
VuoSceneRenderer_renderInternal(sr, cgl_ctx, &texture, GL_TEXTURE_2D, imageGlInternalFormat, multisample, depthImage ? &depthTexture : NULL, invertDepthImage))
1824 *image =
VuoImage_make(texture, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1826 *depthImage =
VuoImage_make(depthTexture, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1842 __block GLuint texture = 0;
1843 __block GLuint depthTexture = 0;
1844 __block
bool renderSucceeded;
1847 vis =
VuoIoSurfacePool_use(cgl_ctx, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, &texture);
1848 renderSucceeded =
VuoSceneRenderer_renderInternal(sr, cgl_ctx, &texture, GL_TEXTURE_RECTANGLE_ARB, imageGlInternalFormat, multisample, includeDepthBuffer ? &depthTexture : NULL,
false);
1850 if (!renderSucceeded)
1856 if (includeDepthBuffer)
1858 VuoImage depthImage =
VuoImage_make(depthTexture, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);