26 #include <OpenGL/CGLMacro.h>
32 "title" :
"Graphics Shader",
33 "description" :
"A graphics shader program, specifying how to render a 3D object.",
34 "keywords" : [
"glsl",
"fragment",
"vertex" ],
92 for (
unsigned int u = 0; u < s->uniformsCount; ++u)
96 if (strcmp(s->uniforms[u].type,
"VuoImage") == 0
97 || strncmp(s->uniforms[u].type,
"VuoList_", 8) == 0
98 || strcmp(s->uniforms[u].type,
"mat2") == 0
99 || strcmp(s->uniforms[u].type,
"mat3") == 0
100 || strcmp(s->uniforms[u].type,
"mat4") == 0)
109 dispatch_release((dispatch_semaphore_t)s->
lock);
131 t->pointProgram.expectedOutputPrimitiveCount = 1;
132 t->lineProgram.expectedOutputPrimitiveCount = 1;
133 t->triangleProgram.expectedOutputPrimitiveCount = 1;
146 t->
lock = dispatch_semaphore_create(1);
181 VuoReal defaultShininess = 0.9;
204 VuoReal defaultShininess = 0.9;
213 #define DEFINE_PROGRAM() \
214 VuoSubshader *program; \
215 VuoMesh_ElementAssemblyMethod epm = VuoMesh_getExpandedPrimitiveMode(inputPrimitiveMode); \
216 if (epm == VuoMesh_IndividualTriangles) \
217 program = &shader->triangleProgram; \
218 else if (epm == VuoMesh_IndividualLines) \
219 program = &shader->lineProgram; \
221 program = &shader->pointProgram;
318 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
323 program->vertexSource =
VuoText_make(vertexShaderSource);
327 \n#include
"VuoGlslProjection.glsl"
330 uniform mat4 modelviewMatrix;
331 attribute vec4 position;
332 attribute vec4 textureCoordinate;
335 varying vec4 fragmentTextureCoordinate;
339 fragmentTextureCoordinate = textureCoordinate;
341 gl_Position = VuoGlsl_projectPosition(modelviewMatrix * position);
344 program->vertexSource =
VuoText_make(defaultVertexShaderSource);
350 program->geometrySource =
VuoText_make(geometryShaderSource);
356 program->fragmentSource =
VuoText_make(fragmentShaderSource);
360 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
380 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
383 program->expectedOutputPrimitiveCount = expectedOutputPrimitiveCount;
385 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
406 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
409 program->mayChangeOutputPrimitiveCount = mayChangeOutputPrimitiveCount;
411 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
441 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
444 unsigned int expectedOutputPrimitiveCount = program->expectedOutputPrimitiveCount;
446 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
448 return expectedOutputPrimitiveCount;
464 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
467 unsigned int mayChangeOutputPrimitiveCount = program->mayChangeOutputPrimitiveCount;
469 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
471 return mayChangeOutputPrimitiveCount;
484 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
486 if (shader->pointProgram.glFragmentShaderName
487 || shader->lineProgram.glFragmentShaderName
488 || shader->triangleProgram.glFragmentShaderName)
490 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
494 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
509 string::size_type beforeFunctionLength = beforeFunction.length();
510 string::size_type pos = 0;
511 while ( (pos = source.find(beforeFunction, pos)) != string::npos )
513 size_t offset = pos + beforeFunctionLength;
515 while (isspace(source[offset]))
518 if (source[offset] !=
'(')
524 VUserLog(
"Syntax error in %s: expected '('.", beforeFunction.c_str());
525 pos += beforeFunctionLength;
530 size_t samplerStart = offset;
531 char samplerEndChar = isThis ?
')' :
',';
532 while (source[offset] != samplerEndChar)
534 size_t samplerEnd = offset;
536 string sampler = source.substr(samplerStart, samplerEnd - samplerStart);
539 source.insert(samplerEnd,
", isf_FragNormCoord");
541 source.insert(samplerEnd,
542 ", _" + sampler +
"_imgRect"
543 +
", _" + sampler +
"_imgSize"
544 +
", _" + sampler +
"_flip");
546 string replacement = afterFunction2D;
548 for (
int i = 0; i < shader->uniformsCount; ++i)
549 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0
550 && shader->uniforms[i].name == sampler
551 && shader->uniforms[i].value.image)
553 target = shader->uniforms[i].value.image->glTextureTarget;
554 if (shader->uniforms[i].value.image->glTextureTarget == GL_TEXTURE_RECTANGLE_EXT)
555 replacement = afterFunctionRect;
560 source.replace(pos, beforeFunctionLength, replacement);
562 imagesToDeclare.insert(std::make_pair(sampler, target));
571 string prefix(before +
"(");
572 string::size_type prefixLength = prefix.length();
573 string::size_type pos = 0;
574 while ( (pos = source.find(prefix, pos)) != string::npos )
576 size_t offset = pos + prefixLength;
577 size_t samplerStart = offset;
578 while (source[offset] !=
')')
580 size_t samplerEnd = offset;
581 string sampler = source.substr(samplerStart, samplerEnd - samplerStart);
582 source.replace(pos, samplerEnd - samplerStart + prefixLength + 1,
"_" + sampler +
"_" + after);
592 map<string, GLint> imagesToDeclare;
593 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_PIXEL",
false,
"VVSAMPLER_2DBYPIXEL",
"VVSAMPLER_2DRECTBYPIXEL", stage, outIssues);
594 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_NORM_PIXEL",
false,
"VVSAMPLER_2DBYNORM",
"VVSAMPLER_2DRECTBYNORM", stage, outIssues);
595 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_THIS_PIXEL",
true,
"texture2D",
"texture2DRect", stage, outIssues);
596 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_THIS_NORM_PIXEL",
true,
"texture2D",
"texture2DRect", stage, outIssues);
602 for (map<string, GLint>::iterator it = imagesToDeclare.begin(); it != imagesToDeclare.end(); ++it)
605 if (it->second == GL_TEXTURE_RECTANGLE_EXT)
606 samplerType =
"sampler2DRect";
608 samplerType =
"sampler2D";
610 string placeholder =
"//uniform VuoImage " + it->first;
611 string replacement =
"uniform " + samplerType +
" " + it->first;
613 string::size_type pos = source.find(placeholder);
614 if (pos == string::npos)
619 VUserLog(
"Unknown image \"%s\".", it->first.c_str());
622 source.replace(pos, placeholder.length(), replacement);
640 if (program->program.programName)
645 bool upToDate =
true;
646 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
647 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0)
648 if (shader->uniforms[i].value.image
663 if (!program->vertexSource)
667 if (program->compilationAttempted)
669 program->compilationAttempted =
true;
671 string vertexSource = program->vertexSource;
673 program->glVertexShaderName =
VuoGlShader_use(glContext, GL_VERTEX_SHADER, vertexSource.c_str(), static_cast<void *>(outIssues));
674 if (!program->glVertexShaderName)
679 string geometrySource = program->geometrySource;
681 program->glGeometryShaderName =
VuoGlShader_use(glContext, GL_GEOMETRY_SHADER_EXT, geometrySource.c_str(), static_cast<void *>(outIssues));
682 if (!program->glGeometryShaderName)
688 string fragmentSource = program->fragmentSource;
690 program->glFragmentShaderName =
VuoGlShader_use(glContext, GL_FRAGMENT_SHADER, fragmentSource.c_str(), static_cast<void *>(outIssues));
691 if (!program->glFragmentShaderName)
695 program->program =
VuoGlProgram_use(glContext, shader->
name, program->glVertexShaderName, program->glGeometryShaderName, program->glFragmentShaderName, inputPrimitiveMode, program->expectedOutputPrimitiveCount, static_cast<void *>(outIssues));
697 return program->program.programName > 0 ? true :
false;
716 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
719 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
723 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
749 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
752 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
759 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
762 if (positionLocation)
763 *positionLocation = glGetAttribLocation(program->program.programName,
"position");
765 *normalLocation = glGetAttribLocation(program->program.programName,
"normal");
767 *tangentLocation = glGetAttribLocation(program->program.programName,
"tangent");
768 if (bitangentLocation)
769 *bitangentLocation = glGetAttribLocation(program->program.programName,
"bitangent");
770 if (textureCoordinateLocation)
771 *textureCoordinateLocation = glGetAttribLocation(program->program.programName,
"textureCoordinate");
774 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
791 int perm[256]= {151,160,137,91,90,15,
792 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
793 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
794 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
795 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
796 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
797 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
798 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
799 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
800 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
801 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
802 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
803 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
805 int grad3[16][3] = {{0,1, 1},{ 0, 1,-1},{ 0,-1,1},{ 0,-1,-1},
806 {1,0, 1},{ 1, 0,-1},{-1, 0,1},{-1, 0,-1},
807 {1,1, 0},{ 1,-1, 0},{-1, 1,0},{-1,-1, 0},
808 {1,0,-1},{-1, 0,-1},{ 0,-1,1},{ 0, 1, 1}};
813 pixels = (
char*)malloc( 256*256*4 );
814 for(i = 0; i<256; i++)
815 for(j = 0; j<256; j++) {
816 int offset = (i*256+j)*4;
817 char value =
perm[(j+
perm[i]) & 0xFF];
818 pixels[offset+2] = grad3[value & 0x0F][0] * 64 + 64;
819 pixels[offset+1] = grad3[value & 0x0F][1] * 64 + 64;
820 pixels[offset+0] = grad3[value & 0x0F][2] * 64 + 64;
821 pixels[offset+3] = value;
824 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
825 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
826 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
827 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
828 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
845 int perm[256]= {151,160,137,91,90,15,
846 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
847 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
848 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
849 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
850 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
851 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
852 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
853 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
854 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
855 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
856 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
857 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
859 int grad4[32][4]= {{ 0, 1,1,1}, { 0, 1, 1,-1}, { 0, 1,-1,1}, { 0, 1,-1,-1},
860 { 0,-1,1,1}, { 0,-1, 1,-1}, { 0,-1,-1,1}, { 0,-1,-1,-1},
861 { 1, 0,1,1}, { 1, 0, 1,-1}, { 1, 0,-1,1}, { 1, 0,-1,-1},
862 {-1, 0,1,1}, {-1, 0, 1,-1}, {-1, 0,-1,1}, {-1, 0,-1,-1},
863 { 1, 1,0,1}, { 1, 1, 0,-1}, { 1,-1, 0,1}, { 1,-1, 0,-1},
864 {-1, 1,0,1}, {-1, 1, 0,-1}, {-1,-1, 0,1}, {-1,-1, 0,-1},
865 { 1, 1,1,0}, { 1, 1,-1, 0}, { 1,-1, 1,0}, { 1,-1,-1, 0},
866 {-1, 1,1,0}, {-1, 1,-1, 0}, {-1,-1, 1,0}, {-1,-1,-1, 0}};
871 pixels = (
char*)malloc( 256*256*4 );
872 for(i = 0; i<256; i++)
873 for(j = 0; j<256; j++) {
874 int offset = (i*256+j)*4;
875 char value =
perm[(j+
perm[i]) & 0xFF];
876 pixels[offset+2] = grad4[value & 0x1F][0] * 64 + 64;
877 pixels[offset+1] = grad4[value & 0x1F][1] * 64 + 64;
878 pixels[offset+0] = grad4[value & 0x1F][2] * 64 + 64;
879 pixels[offset+3] = grad4[value & 0x1F][3] * 64 + 64;
882 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
883 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
885 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
886 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
923 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
927 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
935 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
937 bool alreadyActiveOnThisContext =
false;
943 if (i->second == program->program.programName)
944 alreadyActiveOnThisContext =
true;
946 i->second = program->program.programName;
953 if (!alreadyActiveOnThisContext)
957 glValidateProgram(program->program.programName);
959 int infologLength = 0;
960 glGetProgramiv(program->program.programName, GL_INFO_LOG_LENGTH, &infologLength);
961 if (infologLength > 0)
963 char *infoLog = (
char *)malloc(infologLength);
964 int charsWritten = 0;
965 glGetProgramInfoLog(program->program.programName, infologLength, &charsWritten, infoLog);
971 glUseProgram(program->program.programName);
974 GLuint textureUnit = 0;
975 bool explicitColorBuffer =
false;
976 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
981 if (strncmp(uniform.type,
"VuoList_", 8) == 0)
986 VDebugLog(
"Warning: Shader '%s' has a value for '%s', but the linked program has no uniform by that name.", shader->
name, uniform.name);
991 if (strcmp(uniform.type,
"VuoList_VuoBoolean") == 0)
995 GLint *itemDataGL = (GLint *)malloc(
sizeof(GLint) * itemCount);
996 for (
size_t i = 0; i < itemCount; ++i)
997 itemDataGL[i] = itemData[i];
998 glUniform1iv(location, itemCount, itemDataGL);
1000 else if (strcmp(uniform.type,
"VuoList_VuoInteger") == 0)
1004 GLint *itemDataGL = (GLint *)malloc(
sizeof(GLint) * itemCount);
1005 for (
size_t i = 0; i < itemCount; ++i)
1006 itemDataGL[i] = itemData[i];
1007 glUniform1iv(location, itemCount, itemDataGL);
1009 else if (strcmp(uniform.type,
"VuoList_VuoReal") == 0)
1013 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount);
1014 for (
size_t i = 0; i < itemCount; ++i)
1015 itemDataGL[i] = itemData[i];
1016 glUniform1fv(location, itemCount, itemDataGL);
1018 else if (strcmp(uniform.type,
"VuoList_VuoPoint2d") == 0)
1022 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 2);
1023 for (
size_t i = 0; i < itemCount; ++i)
1025 itemDataGL[i*2 + 0] = itemData[i].x;
1026 itemDataGL[i*2 + 1] = itemData[i].y;
1028 glUniform2fv(location, itemCount, itemDataGL);
1030 else if (strcmp(uniform.type,
"VuoList_VuoPoint3d") == 0)
1034 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 3);
1035 for (
size_t i = 0; i < itemCount; ++i)
1037 itemDataGL[i*3 + 0] = itemData[i].x;
1038 itemDataGL[i*3 + 1] = itemData[i].y;
1039 itemDataGL[i*3 + 2] = itemData[i].z;
1041 glUniform3fv(location, itemCount, itemDataGL);
1043 else if (strcmp(uniform.type,
"VuoList_VuoPoint4d") == 0)
1047 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 4);
1048 for (
size_t i = 0; i < itemCount; ++i)
1050 itemDataGL[i*4 + 0] = itemData[i].x;
1051 itemDataGL[i*4 + 1] = itemData[i].y;
1052 itemDataGL[i*4 + 2] = itemData[i].z;
1053 itemDataGL[i*4 + 3] = itemData[i].w;
1055 glUniform4fv(location, itemCount, itemDataGL);
1057 else if (strcmp(uniform.type,
"VuoList_VuoColor") == 0)
1061 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 4);
1062 for (
size_t i = 0; i < itemCount; ++i)
1064 itemDataGL[i*4 + 0] = itemData[i].r;
1065 itemDataGL[i*4 + 1] = itemData[i].g;
1066 itemDataGL[i*4 + 2] = itemData[i].b;
1067 itemDataGL[i*4 + 3] = itemData[i].a;
1069 glUniform4fv(location, itemCount, itemDataGL);
1072 VDebugLog(
"Warning: Shader '%s' has unknown type '%s' for uniform '%s'.", shader->
name, uniform.type, uniform.name);
1075 if (listLengthUniform != -1)
1076 glUniform1i(listLengthUniform, itemCount);
1083 if (strcmp(uniform.type,
"VuoImage") == 0 && uniform.value.image)
1085 VuoImage image = uniform.value.image;
1089 if (imgRectUniform != -1)
1092 glUniform4f(imgRectUniform, 0, 0, 1, 1);
1098 if (imgSizeUniform != -1)
1103 if (flipUniform != -1)
1104 glUniform1i(flipUniform, 0);
1110 VDebugLog(
"Warning: Shader '%s' has a value for '%s', but the linked program has no uniform by that name.", shader->
name, uniform.name);
1114 if (strcmp(uniform.type,
"VuoImage") == 0)
1116 VuoImage image = uniform.value.image;
1118 glActiveTexture(GL_TEXTURE0 + textureUnit);
1128 glBindTexture(GL_TEXTURE_2D, 0);
1129 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1131 glUniform1i(location, textureUnit);
1134 if (strcmp(uniform.name,
"colorBuffer") == 0)
1135 explicitColorBuffer =
true;
1137 else if (strcmp(uniform.type,
"VuoBoolean") == 0)
1138 glUniform1i(location, uniform.value.boolean);
1139 else if (strcmp(uniform.type,
"VuoInteger") == 0)
1140 glUniform1i(location, uniform.value.integer);
1141 else if (strcmp(uniform.type,
"VuoReal") == 0)
1142 glUniform1f(location, uniform.value.real);
1143 else if (strcmp(uniform.type,
"VuoPoint2d") == 0)
1144 glUniform2f(location, uniform.value.point2d.x, uniform.value.point2d.y);
1145 else if (strcmp(uniform.type,
"VuoPoint3d") == 0)
1146 glUniform3f(location, uniform.value.point3d.x, uniform.value.point3d.y, uniform.value.point3d.z);
1147 else if (strcmp(uniform.type,
"VuoPoint4d") == 0)
1148 glUniform4f(location, uniform.value.point4d.x, uniform.value.point4d.y, uniform.value.point4d.z, uniform.value.point4d.w);
1149 else if (strcmp(uniform.type,
"VuoColor") == 0)
1150 glUniform4f(location, uniform.value.color.r, uniform.value.color.g, uniform.value.color.b, uniform.value.color.a);
1151 else if (strcmp(uniform.type,
"mat2") == 0)
1152 glUniformMatrix2fv(location, 1, GL_FALSE, uniform.value.mat2);
1153 else if (strcmp(uniform.type,
"mat3") == 0)
1154 glUniformMatrix3fv(location, 1, GL_FALSE, uniform.value.mat3);
1155 else if (strcmp(uniform.type,
"mat4") == 0)
1156 glUniformMatrix4fv(location, 1, GL_FALSE, uniform.value.mat4);
1158 VUserLog(
"Error: Unknown type %s for '%s'", uniform.type, uniform.name);
1163 if (perlinTextureUniform != -1)
1165 glActiveTexture(GL_TEXTURE0 + textureUnit);
1167 static dispatch_once_t initPerlinTexture = 0;
1168 dispatch_once(&initPerlinTexture, ^{
1173 glUniform1i(perlinTextureUniform, textureUnit);
1178 if (gradTextureUniform != -1)
1180 glActiveTexture(GL_TEXTURE0 + textureUnit);
1182 static dispatch_once_t initGradTexture = 0;
1183 dispatch_once(&initGradTexture, ^{
1188 glUniform1i(gradTextureUniform, textureUnit);
1196 GLint width, height;
1197 if ((!explicitColorBuffer && colorBufferUniform != -1) || depthBufferUniform != -1)
1200 glGetIntegerv(GL_VIEWPORT, viewport);
1201 width = viewport[2];
1202 height = viewport[3];
1205 if (!explicitColorBuffer && colorBufferUniform != -1)
1208 glActiveTexture(GL_TEXTURE0 + textureUnit);
1210 GLuint colorBufferTexture =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, NULL);
1211 glBindTexture(GL_TEXTURE_2D, colorBufferTexture);
1213 GLint multisampling, multisampledFramebuffer;
1214 glGetIntegerv(GL_SAMPLE_BUFFERS, &multisampling);
1215 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &multisampledFramebuffer);
1216 if (multisampling && multisampledFramebuffer)
1218 GLuint resolvedFramebuffer;
1219 glGenFramebuffers(1, &resolvedFramebuffer);
1220 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFramebuffer);
1223 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTexture, 0);
1225 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, multisampledFramebuffer);
1226 glReadBuffer(GL_COLOR_ATTACHMENT0);
1227 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1228 glBlitFramebuffer(0, 0, width, height,
1229 0, 0, width, height,
1230 GL_COLOR_BUFFER_BIT,
1233 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1236 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, multisampledFramebuffer);
1237 glDeleteFramebuffers(1, &resolvedFramebuffer);
1240 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);
1245 glUniform1i(colorBufferUniform, textureUnit);
1249 if (depthBufferUniform != -1)
1252 glActiveTexture(GL_TEXTURE0 + textureUnit);
1254 GLuint depthBufferTexture =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_DEPTH_COMPONENT16, width, height, GL_DEPTH_COMPONENT, NULL);
1255 glBindTexture(GL_TEXTURE_2D, depthBufferTexture);
1258 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, 0, width, height, 0);
1263 glUniform1i(depthBufferUniform, textureUnit);
1274 if (timedeltaUniform != -1)
1279 if (dateUniform != -1)
1288 glUniform4f(dateUniform, (
float)year, (
float)month, (
float)dayOfMonth, (
float)(second + (minute + (hour * 60)) * 60));
1292 if (frameindexUniform != -1)
1299 *outputProgram = program->program;
1330 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1332 GLuint textureUnit = 0;
1333 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
1339 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0)
1341 VuoImage image = shader->uniforms[i].value.image;
1345 glActiveTexture(GL_TEXTURE0 + textureUnit);
1353 glActiveTexture(GL_TEXTURE0 + textureUnit);
1354 glBindTexture(GL_TEXTURE_2D, 0);
1360 glActiveTexture(GL_TEXTURE0 + textureUnit);
1361 glBindTexture(GL_TEXTURE_2D, 0);
1367 glActiveTexture(GL_TEXTURE0 + textureUnit);
1368 glBindTexture(GL_TEXTURE_2D, 0);
1376 glActiveTexture(GL_TEXTURE0 + textureUnit);
1377 glBindTexture(GL_TEXTURE_2D, 0);
1387 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
1403 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1421 if (json_object_object_get_ex(js,
"pointer", &o))
1422 return (
VuoShader)json_object_get_int64(o);
1440 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1462 return strdup(
"No shader");
1464 return strdup(value->
name);
1481 VuoPoint2d samplerCoordinates;
1484 return samplerCoordinates;
1542 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
1544 for (
int i = 0; i < shader->uniformsCount; ++i)
1546 if (strcmp(shader->uniforms[i].type,
"VuoColor") == 0
1554 if (strcmp(shader->uniforms[i].type,
"VuoList_VuoColor") == 0
1562 if (strcmp(shader->uniforms[i].type,
"VuoReal") == 0
1563 && strcmp(shader->uniforms[i].name,
"alpha") == 0
1564 && shader->uniforms[i].value.real < 1)
1571 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0
1572 && shader->uniforms[i].value.image
1582 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);