365 float aspectRatio = (float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight;
367 if (type == VuoSceneObjectSubType_PerspectiveCamera)
384 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
390 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
393 else if (type == VuoSceneObjectSubType_StereoCamera)
397 float top = cameraDistanceMin * tanf(halfFieldOfView);
398 float right = aspectRatio * top;
400 if (!sceneRenderer->useLeftCamera)
401 frustumshift *= -1.f;
418 sceneRenderer->
projectionMatrix[10] = (cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMin - cameraDistanceMax);
422 sceneRenderer->
projectionMatrix[12] = (sceneRenderer->useLeftCamera ? 1.f : -1.f) * cameraIntraocularDistance / 2.f;
424 sceneRenderer->
projectionMatrix[14] = 2.f * cameraDistanceMax * cameraDistanceMin / (cameraDistanceMin - cameraDistanceMax);
427 else if (type == VuoSceneObjectSubType_OrthographicCamera)
430 float halfWidth = cameraWidth / 2.f;
445 sceneRenderer->
projectionMatrix[10] = -2.f / (cameraDistanceMax - cameraDistanceMin);
451 sceneRenderer->
projectionMatrix[14] = -(cameraDistanceMax + cameraDistanceMin) / (cameraDistanceMax - cameraDistanceMin);
454 else if (type == VuoSceneObjectSubType_FisheyeCamera)
458 VuoSceneRendererPro_generateFisheyeProjectionMatrix(sceneRenderer, sceneRenderer->camera, aspectRatio);
468 float cameraMatrix[16];
471 float invertedCameraMatrix[16];
504 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
507 VUserLog(
"Error: Vertex attrib array isn't enabled.");
511 unsigned int vertexCount, combinedBuffer, elementCount;
512 VuoMesh_getGPUBuffers(mesh, &vertexCount, &combinedBuffer,
nullptr,
nullptr,
nullptr, &elementCount,
nullptr);
515 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &vaovbo);
516 if (vaovbo != (GLint)combinedBuffer)
517 VUserLog(
"Error: GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING (%d) doesn't match submesh's VBO (%d).", vaovbo, combinedBuffer);
519 GLint vertexBufferBound = -1;
520 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertexBufferBound);
521 if (vertexBufferBound)
522 VUserLog(
"Error: GL_ARRAY_BUFFER_BINDING is %d (it should probably be 0, since we're using a VAO).", vertexBufferBound);
524 GLint elementBufferBound = -1;
525 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elementBufferBound);
526 if (elementCount && !elementBufferBound)
527 VUserLog(
"Error: GL_ELEMENT_ARRAY_BUFFER_BINDING is 0 (it should be nonzero, since we're trying to draw elements).");
529 GLint combinedBufferSize = -1;
530 glBindBuffer(GL_ARRAY_BUFFER, combinedBuffer);
531 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &combinedBufferSize);
532 glBindBuffer(GL_ARRAY_BUFFER, 0);
533 if (combinedBufferSize < 4)
534 VUserLog(
"Error: combinedBuffer is unrealistically small (%d bytes).", combinedBufferSize);
536 GLint attribStride = -1;
537 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attribStride);
539 GLint attribComponents = -1;
540 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attribComponents);
542 GLint attribType = -1;
543 glGetVertexAttribiv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attribType);
545 void *attribBase = (
void *)0;
546 glGetVertexAttribPointerv(positionAttribute, GL_VERTEX_ATTRIB_ARRAY_POINTER, &attribBase);
548 unsigned int bytesPerComponent;
549 if (attribType == GL_UNSIGNED_INT)
550 bytesPerComponent = 1;
551 else if (attribType == GL_FLOAT)
552 bytesPerComponent = 4;
559 unsigned int minIndex = 0;
560 unsigned int maxIndex = 0;
564 if (elementBufferSize != elementCount *
sizeof(
unsigned int))
565 VUserLog(
"Error: elementBufferSize doesn't match elementCount.");
567 unsigned int *b = (
unsigned int *)malloc(elementBufferSize);
568 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, elementBufferSize, b);
570 for (
unsigned int i = 0; i < elementCount; ++i)
581 maxIndex = vertexCount - 1;
583 long startWithinVBO = (long)attribBase + (
unsigned int)attribStride * minIndex;
584 long endWithinVBO = (long)attribBase +(
unsigned int) attribStride * maxIndex + (
unsigned int)attribComponents * bytesPerComponent;
586 if (startWithinVBO < 0)
588 if (endWithinVBO < 0)
590 if (startWithinVBO > endWithinVBO)
592 if (endWithinVBO > combinedBufferSize)
593 VUserLog(
"Error: end > combinedBufferSize");
625 float verticalScale = 1.;
626 float rotationZ = 0.;
635 font.pointSize *= transform.scale.x;
636 wrapWidth *= transform.scale.x;
637 verticalScale = transform.scale.y / transform.scale.x;
641 VuoPoint2d corners[4];
644 VuoPoint2d anchorOffset =
VuoSceneText_getAnchorOffset(so, verticalScale, rotationZ, wrapWidth, sceneRenderer->viewportWidth, sceneRenderer->backingScaleFactor);
645 modelviewMatrix[12] += anchorOffset.x;
646 modelviewMatrix[13] += anchorOffset.y;
656 if (isRealSize && !image)
659 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
662 GLuint timeElapsedQuery;
663 glGenQueries(1, &timeElapsedQuery);
664 glBeginQuery(GL_TIME_ELAPSED_EXT, timeElapsedQuery);
667 GLint positionAttribute = -1;
670 VDebugLog(
"Error: Couldn't fetch the 'position' attribute, needed to check data bounds.");
676 VUserLog(
"Shader activation failed.");
682 glUniformMatrix4fv(projectionMatrixUniform, 1, GL_FALSE, projectionMatrix);
685 if (useFisheyeProjectionUniform != -1)
686 glUniform1i(useFisheyeProjectionUniform,
VuoSceneObject_getType(sceneRenderer->camera) == VuoSceneObjectSubType_FisheyeCamera);
692 float billboardMatrix[16];
695 VuoPoint2d mesh0 = (VuoPoint2d){ positions[0], positions[1] };
696 VuoTransform_getBillboardMatrix(image->pixelsWide, image->pixelsHigh, image->scaleFactor,
VuoSceneObject_shouldPreservePhysicalSize(so), modelviewMatrix[12], modelviewMatrix[13], sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, sceneRenderer->backingScaleFactor, mesh0, billboardMatrix);
697 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, billboardMatrix);
700 glUniformMatrix4fv(modelviewMatrixUniform, 1, GL_FALSE, modelviewMatrix);
703 if (cameraMatrixInverseUniform != -1)
704 glUniformMatrix4fv(cameraMatrixInverseUniform, 1, GL_FALSE, sceneRenderer->
cameraMatrixInverse);
707 if (cameraPositionUniform != -1)
710 glUniform3f(cameraPositionUniform, p.x, p.y, p.z);
714 if (aspectRatioUniform != -1)
715 glUniform1f(aspectRatioUniform, (
float)sceneRenderer->viewportWidth/(
float)sceneRenderer->viewportHeight);
718 if (viewportSizeUniform != -1)
719 glUniform2f(viewportSizeUniform, (
float)sceneRenderer->viewportWidth, (
float)sceneRenderer->viewportHeight);
722 if (ambientColorUniform != -1)
725 glUniform4f(ambientColorUniform,
726 pow(sceneRenderer->ambientColor.r, 2.2) * sceneRenderer->ambientColor.a,
727 pow(sceneRenderer->ambientColor.g, 2.2) * sceneRenderer->ambientColor.a,
728 pow(sceneRenderer->ambientColor.b, 2.2) * sceneRenderer->ambientColor.a,
729 sceneRenderer->ambientColor.a);
731 if (ambientBrightnessUniform != -1)
732 glUniform1f(ambientBrightnessUniform, pow(sceneRenderer->ambientBrightness, 2.2));
734 size_t uniformSize = 27;
735 char uniformName[uniformSize];
739 if (pointLightCountUniform != -1)
741 glUniform1i(pointLightCountUniform, pointLightCount);
743 strlcpy(uniformName,
"pointLights[", uniformSize);
744 const int prefixLength = 12;
746 for (
int i=1; i<=pointLightCount; ++i)
755 glUniform4f(colorUniform,
768 glUniform3f(positionUniform, p.x, p.y, p.z);
782 if (spotLightCountUniform != -1)
784 glUniform1i(spotLightCountUniform, spotLightCount);
786 strlcpy(uniformName,
"spotLights[", uniformSize);
787 const int prefixLength = 11;
789 for (
int i=1; i<=spotLightCount; ++i)
798 glUniform4f(colorUniform,
811 glUniform3f(positionUniform, p.x, p.y, p.z);
816 glUniform3f(directionUniform, direction.x, direction.y, direction.z);
880 unsigned int vertexCount, elementCount;
881 void *textureCoordinateOffset, *colorOffset;
882 VuoMesh_getGPUBuffers(mesh, &vertexCount,
nullptr,
nullptr, &textureCoordinateOffset, &colorOffset, &elementCount,
nullptr);
885 if (hasTextureCoordinatesUniform != -1)
886 glUniform1i(hasTextureCoordinatesUniform, textureCoordinateOffset != NULL);
889 if (hasVertexColorsUniform != -1)
890 glUniform1i(hasVertexColorsUniform, colorOffset !=
nullptr);
893 if (primitiveHalfSizeUniform != -1)
897 bool enableCulling = faceCullingGL != GL_NONE && !shader->isTransparent;
910 glDrawElements(mode, completeInputElementCount, GL_UNSIGNED_INT, (
void*)0);
911 else if (vertexCount)
912 glDrawArrays(mode, 0, completeInputElementCount);
920 glEndQuery(GL_TIME_ELAPSED_EXT);
922 glGetQueryObjectuiv(timeElapsedQuery, GL_QUERY_RESULT, &nanoseconds);
923 seconds = ((double)nanoseconds) / NSEC_PER_SEC;
924 glDeleteQueries(1, &timeElapsedQuery);
926 std::string description = so.name ? std::string(so.name) :
"no name";
927 description += std::string(
" (") + shader->name +
")";
928 sceneRenderer->profileTimes.push_back(make_pair(description, seconds));
1001 VLog(
"Render lists:");
1003 for (
auto currentState : sceneRenderer->opaqueObjects)
1005 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
1006 currentState.modelviewMatrix[12],
1007 currentState.modelviewMatrix[13],
1008 currentState.modelviewMatrix[14],
1009 currentState.so->shader ? currentState.so->shader->name : NULL
1012 VLog(
" Potentially Transparent:");
1013 for (
auto currentState : sceneRenderer->potentiallyTransparentObjects)
1015 VLog(
" '%s' @ %g,%g,%g with '%s'", currentState.so->name,
1016 currentState.modelviewMatrix[12],
1017 currentState.modelviewMatrix[13],
1018 currentState.modelviewMatrix[14],
1019 currentState.so->shader->name
1027 bzero(&sceneRenderer->glState,
sizeof(sceneRenderer->glState));
1028 sceneRenderer->glState.vGL_DEPTH_MASK =
true;
1029 sceneRenderer->glState.vGL_DEPTH_TEST =
false;
1030 sceneRenderer->glState.vGL_CULL_FACE =
true;
1031 sceneRenderer->glState.vGL_CULL_FACE_MODE = GL_BACK;
1032 sceneRenderer->glState.vGL_BLEND_SRC_RGB = GL_ONE;
1033 sceneRenderer->glState.vGL_BLEND_DST_RGB = GL_ONE_MINUS_SRC_ALPHA;
1034 sceneRenderer->glState.vGL_BLEND_SRC_ALPHA = GL_ONE;
1035 sceneRenderer->glState.vGL_BLEND_DST_ALPHA = GL_ONE_MINUS_SRC_ALPHA;
1036 sceneRenderer->glState.vGL_BLEND_EQUATION_RGB = GL_FUNC_ADD;
1037 sceneRenderer->glState.vGL_BLEND_EQUATION_ALPHA = GL_FUNC_ADD;
1038 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_COVERAGE =
false;
1039 sceneRenderer->glState.vGL_SAMPLE_ALPHA_TO_ONE =
false;
1045 if (!sceneRenderer->potentiallyTransparentObjects.empty())
1064 VuoSceneRendererPro_drawVignette(sceneRenderer, cgl_ctx);
1069 VLog(
"Object render time (percent of a 60 Hz frame)");
1070 double totalPercent = 0;
1071 sceneRenderer->profileTimes.sort(VuoProfileSort);
1072 for (std::list<VuoProfileEntry>::iterator i = sceneRenderer->profileTimes.begin(); i != sceneRenderer->profileTimes.end(); ++i)
1074 double objectPercent = i->second / (1./60.) * 100.;
1075 VLog(
" %6.2f %s", objectPercent, i->first.c_str());
1076 totalPercent += objectPercent;
1078 VLog(
" ------ -----");
1079 VLog(
" %6.2f total", totalPercent);
1080 sceneRenderer->profileTimes.clear();
1083 glFlushRenderAPPLE();
1088#pragma clang diagnostic push
1089#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1090 CGLGetParameter(cgl_ctx, kCGLCPCurrentRendererID, &rendererID);
1091#pragma clang diagnostic pop
1092 if (rendererID != sceneRenderer->glContextRendererID)
1095 sceneRenderer->glContextRendererID = rendererID;
1332 if (!sceneRenderer->sharedTextOverrideShader)
1335 VuoRetain(sceneRenderer->sharedTextOverrideShader);
1355 VuoSceneRendererMeshShaderVAOs::iterator i = sceneRenderer->
meshShaderItems.find(meshShader);
1358 soi->
vao = i->second;
1365 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1369 GLint positionAttribute, normalAttribute, textureCoordinateAttribute, colorAttribute;
1371 VUserLog(
"Error: Couldn't fetch the shader's attribute locations.");
1373 unsigned int combinedBuffer, elementCount, elementBuffer;
1374 void *normalOffset, *textureCoordinateOffset, *colorOffset;
1375 VuoMesh_getGPUBuffers(mesh,
nullptr, &combinedBuffer, &normalOffset, &textureCoordinateOffset, &colorOffset, &elementCount, &elementBuffer);
1386 glBindBuffer(GL_ARRAY_BUFFER, combinedBuffer);
1391 int stride =
sizeof(float) * 3;
1392 glEnableVertexAttribArray((GLuint)positionAttribute);
1393 glVertexAttribPointer((GLuint)positionAttribute, 3 , GL_FLOAT, GL_FALSE, stride, (
void*)0);
1395 if (normalOffset && normalAttribute>=0)
1397 glEnableVertexAttribArray((GLuint)normalAttribute);
1398 glVertexAttribPointer((GLuint)normalAttribute, 3 , GL_FLOAT, GL_FALSE, stride, normalOffset);
1401 if (textureCoordinateOffset && textureCoordinateAttribute>=0)
1403 glEnableVertexAttribArray((GLuint)textureCoordinateAttribute);
1404 glVertexAttribPointer((GLuint)textureCoordinateAttribute, 2 , GL_FLOAT, GL_FALSE,
sizeof(
float) * 2, textureCoordinateOffset);
1407 if (colorOffset && colorAttribute >= 0)
1409 glEnableVertexAttribArray((GLuint)colorAttribute);
1410 glVertexAttribPointer((GLuint)colorAttribute, 4 , GL_FLOAT, GL_FALSE,
sizeof(
float) * 4, colorOffset);
1415 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
1420 soi->
vao = vertexArray;
1422 glBindBuffer(GL_ARRAY_BUFFER, 0);
1664 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1666 static bool force2DDepth =
true;
1667 static dispatch_once_t once = 0;
1668 dispatch_once(&once, ^{
1670 Boolean overridden =
false;
1671 force2DDepth = (int)CFPreferencesGetAppIntegerValue(CFSTR(
"force2DDepth"), CFSTR(
"org.vuo.Editor"), &overridden);
1681 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1682 if (strcmp(renderer,
"NVIDIA GeForce GT 650M OpenGL Engine") == 0
1683 || strcmp(renderer,
"NVIDIA GeForce 9400M OpenGL Engine") == 0)
1684 force2DDepth =
false;
1686 force2DDepth =
true;
1689 VUserLog(
"force2DDepth = %d", force2DDepth);
1693 unsigned long requiredBytes = sceneRenderer->viewportWidth * sceneRenderer->viewportHeight * colorBytesPerPixel;
1694 if (outputDepthTexture)
1695 requiredBytes += sceneRenderer->viewportWidth * sceneRenderer->viewportHeight *
VuoGlTexture_getBytesPerPixel(GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
1699 bool actuallyMultisampling = multisample > 1;
1702 const char *renderer = (
const char *)glGetString(GL_RENDERER);
1703 if (strcmp(renderer,
"Intel HD Graphics 3000") == 0)
1708 requiredBytes += requiredBytes * multisample * fudge;
1711 if (maximumTextureBytes > 0 && requiredBytes > maximumTextureBytes)
1713 VUserLog(
"Not enough graphics memory for a %dx%d (%d bytes/pixel * %d sample) render%s. Requires %lu MB, have %lu MB.",
1714 sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1715 colorBytesPerPixel, multisample==0?1:multisample,
1716 outputDepthTexture ?
" with depth buffer" :
"",
1717 requiredBytes/1024/1024, maximumTextureBytes/1024/1024);
1723 if (!*outputTexture)
1724 *outputTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_BGRA, NULL);
1726 if (outputDepthTexture)
1727 *outputDepthTexture =
VuoGlTexturePool_use(glContext, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight, GL_DEPTH_COMPONENT, NULL);
1729 if (!*outputTexture || (outputDepthTexture && !*outputDepthTexture))
1734 glBindFramebuffer(GL_FRAMEBUFFER, sceneRenderer->outputFramebuffer);
1738 if (actuallyMultisampling)
1740 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1742 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, imageGlInternalFormat, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1743 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER_EXT, sceneRenderer->renderBuffer);
1745 if (outputDepthTexture)
1747 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1748 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, GL_DEPTH_COMPONENT, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1749 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER_EXT, sceneRenderer->renderDepthBuffer);
1754 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1755 if (outputDepthTexture)
1756 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1763 if (invertDepthImage)
1767 glDepthFunc(GL_GREATER);
1773 glDepthFunc(GL_LESS);
1776 glViewport(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight);
1777 glClearColor(0,0,0,0);
1778 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1785 if (actuallyMultisampling)
1787 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, sceneRenderer->outputFramebuffer2);
1790 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, *outputTexture, 0);
1791 if (outputDepthTexture)
1792 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, *outputDepthTexture, 0);
1794 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, sceneRenderer->outputFramebuffer);
1795 glReadBuffer(GL_COLOR_ATTACHMENT0);
1796 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1797 glBlitFramebufferEXT(0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1798 0, 0, sceneRenderer->viewportWidth, sceneRenderer->viewportHeight,
1799 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1802 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1803 if (outputDepthTexture)
1804 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1807 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1811 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0);
1812 if (outputDepthTexture)
1813 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, force2DDepth ? GL_TEXTURE_2D : target, 0, 0);
1817 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1821 glFlushRenderAPPLE();