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;
316 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
321 program->vertexSource =
VuoText_make(vertexShaderSource);
325 \n#include
"VuoGlslProjection.glsl"
328 uniform mat4 modelviewMatrix;
329 attribute vec3 position;
330 attribute vec2 textureCoordinate;
333 varying vec2 fragmentTextureCoordinate;
337 fragmentTextureCoordinate = textureCoordinate;
339 gl_Position = VuoGlsl_projectPosition(modelviewMatrix * vec4(position, 1.));
343 \n#include
"VuoGlslProjection.glsl"
346 uniform mat4 modelviewMatrix;
347 attribute vec3 position;
348 attribute vec2 textureCoordinate;
349 attribute vec4 vertexColor;
350 uniform
bool hasVertexColors;
353 varying vec2 fragmentTextureCoordinate;
354 varying vec4 fragmentVertexColor;
358 fragmentTextureCoordinate = textureCoordinate;
359 fragmentVertexColor = hasVertexColors ? vertexColor : vec4(1.);
361 gl_Position = VuoGlsl_projectPosition(modelviewMatrix * vec4(position, 1.));
365 if (strstr(fragmentShaderSource,
"fragmentVertexColor"))
366 program->vertexSource =
VuoText_make(defaultVertexShaderWithColorSource);
368 program->vertexSource =
VuoText_make(defaultVertexShaderSource);
374 program->geometrySource =
VuoText_make(geometryShaderSource);
380 program->fragmentSource =
VuoText_make(fragmentShaderSource);
384 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
404 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
407 program->expectedOutputPrimitiveCount = expectedOutputPrimitiveCount;
409 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
430 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
433 program->mayChangeOutputPrimitiveCount = mayChangeOutputPrimitiveCount;
435 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
465 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
468 unsigned int expectedOutputPrimitiveCount = program->expectedOutputPrimitiveCount;
470 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
472 return expectedOutputPrimitiveCount;
488 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
491 unsigned int mayChangeOutputPrimitiveCount = program->mayChangeOutputPrimitiveCount;
493 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
495 return mayChangeOutputPrimitiveCount;
508 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
510 if (shader->pointProgram.glFragmentShaderName
511 || shader->lineProgram.glFragmentShaderName
512 || shader->triangleProgram.glFragmentShaderName)
514 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
518 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
533 string::size_type beforeFunctionLength = beforeFunction.length();
534 string::size_type pos = 0;
535 while ( (pos = source.find(beforeFunction, pos)) != string::npos )
537 size_t offset = pos + beforeFunctionLength;
539 while (isspace(source[offset]))
542 if (source[offset] !=
'(')
548 VUserLog(
"Syntax error in %s: expected '('.", beforeFunction.c_str());
549 pos += beforeFunctionLength;
554 size_t samplerStart = offset;
555 char samplerEndChar = isThis ?
')' :
',';
556 while (source[offset] != samplerEndChar)
558 size_t samplerEnd = offset;
560 string sampler = source.substr(samplerStart, samplerEnd - samplerStart);
563 source.insert(samplerEnd,
", isf_FragNormCoord");
565 source.insert(samplerEnd,
566 ", _" + sampler +
"_imgRect"
567 +
", _" + sampler +
"_imgSize"
568 +
", _" + sampler +
"_flip");
570 string replacement = afterFunction2D;
572 for (
int i = 0; i < shader->uniformsCount; ++i)
573 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0
574 && shader->uniforms[i].name == sampler
575 && shader->uniforms[i].value.image)
577 target = shader->uniforms[i].value.image->glTextureTarget;
578 if (shader->uniforms[i].value.image->glTextureTarget == GL_TEXTURE_RECTANGLE_EXT)
579 replacement = afterFunctionRect;
584 source.replace(pos, beforeFunctionLength, replacement);
586 imagesToDeclare.insert(std::make_pair(sampler, target));
595 string prefix(before +
"(");
596 string::size_type prefixLength = prefix.length();
597 string::size_type pos = 0;
598 while ( (pos = source.find(prefix, pos)) != string::npos )
600 size_t offset = pos + prefixLength;
601 size_t samplerStart = offset;
602 while (source[offset] !=
')')
604 size_t samplerEnd = offset;
605 string sampler = source.substr(samplerStart, samplerEnd - samplerStart);
606 source.replace(pos, samplerEnd - samplerStart + prefixLength + 1,
"_" + sampler +
"_" + after);
616 map<string, GLint> imagesToDeclare;
617 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_PIXEL",
false,
"VVSAMPLER_2DBYPIXEL",
"VVSAMPLER_2DRECTBYPIXEL", stage, outIssues);
618 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_NORM_PIXEL",
false,
"VVSAMPLER_2DBYNORM",
"VVSAMPLER_2DRECTBYNORM", stage, outIssues);
619 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_THIS_PIXEL",
true,
"texture2D",
"texture2DRect", stage, outIssues);
620 VuoShader_replaceImageMacro(shader, source, imagesToDeclare,
"IMG_THIS_NORM_PIXEL",
true,
"texture2D",
"texture2DRect", stage, outIssues);
626 for (map<string, GLint>::iterator it = imagesToDeclare.begin(); it != imagesToDeclare.end(); ++it)
629 if (it->second == GL_TEXTURE_RECTANGLE_EXT)
630 samplerType =
"sampler2DRect";
632 samplerType =
"sampler2D";
634 string placeholder =
"//uniform VuoImage " + it->first;
635 string replacement =
"uniform " + samplerType +
" " + it->first;
637 string::size_type pos = source.find(placeholder);
638 if (pos == string::npos)
643 VUserLog(
"Unknown image \"%s\".", it->first.c_str());
646 source.replace(pos, placeholder.length(), replacement);
664 if (program->program.programName)
669 bool upToDate =
true;
670 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
671 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0)
672 if (shader->uniforms[i].value.image
687 if (!program->vertexSource)
691 if (program->compilationAttempted)
693 program->compilationAttempted =
true;
695 string vertexSource = program->vertexSource;
697 program->glVertexShaderName =
VuoGlShader_use(glContext, GL_VERTEX_SHADER, vertexSource.c_str(),
static_cast<void *
>(outIssues));
698 if (!program->glVertexShaderName)
703 string geometrySource = program->geometrySource;
705 program->glGeometryShaderName =
VuoGlShader_use(glContext, GL_GEOMETRY_SHADER_EXT, geometrySource.c_str(),
static_cast<void *
>(outIssues));
706 if (!program->glGeometryShaderName)
712 string fragmentSource = program->fragmentSource;
714 program->glFragmentShaderName =
VuoGlShader_use(glContext, GL_FRAGMENT_SHADER, fragmentSource.c_str(),
static_cast<void *
>(outIssues));
715 if (!program->glFragmentShaderName)
719 program->program =
VuoGlProgram_use(glContext, shader->
name, program->glVertexShaderName, program->glGeometryShaderName, program->glFragmentShaderName, inputPrimitiveMode, program->expectedOutputPrimitiveCount,
static_cast<void *
>(outIssues));
721 return program->program.programName > 0 ? true :
false;
740 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
743 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
747 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
772 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
775 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
782 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
785 if (positionLocation)
786 *positionLocation = glGetAttribLocation(program->program.programName,
"position");
788 *normalLocation = glGetAttribLocation(program->program.programName,
"normal");
789 if (textureCoordinateLocation)
790 *textureCoordinateLocation = glGetAttribLocation(program->program.programName,
"textureCoordinate");
792 *colorLocation = glGetAttribLocation(program->program.programName,
"vertexColor");
795 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
812 int perm[256]= {151,160,137,91,90,15,
813 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
814 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
815 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
816 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
817 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
818 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
819 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
820 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
821 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
822 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
823 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
824 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
826 int grad3[16][3] = {{0,1, 1},{ 0, 1,-1},{ 0,-1,1},{ 0,-1,-1},
827 {1,0, 1},{ 1, 0,-1},{-1, 0,1},{-1, 0,-1},
828 {1,1, 0},{ 1,-1, 0},{-1, 1,0},{-1,-1, 0},
829 {1,0,-1},{-1, 0,-1},{ 0,-1,1},{ 0, 1, 1}};
834 pixels = (
char*)malloc( 256*256*4 );
835 for(i = 0; i<256; i++)
836 for(j = 0; j<256; j++) {
837 int offset = (i*256+j)*4;
838 char value =
perm[(j+
perm[i]) & 0xFF];
839 pixels[offset+2] = grad3[value & 0x0F][0] * 64 + 64;
840 pixels[offset+1] = grad3[value & 0x0F][1] * 64 + 64;
841 pixels[offset+0] = grad3[value & 0x0F][2] * 64 + 64;
842 pixels[offset+3] = value;
845 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
846 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
847 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
848 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
849 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
866 int perm[256]= {151,160,137,91,90,15,
867 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
868 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
869 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
870 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
871 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
872 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
873 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
874 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
875 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
876 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
877 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
878 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180};
880 int grad4[32][4]= {{ 0, 1,1,1}, { 0, 1, 1,-1}, { 0, 1,-1,1}, { 0, 1,-1,-1},
881 { 0,-1,1,1}, { 0,-1, 1,-1}, { 0,-1,-1,1}, { 0,-1,-1,-1},
882 { 1, 0,1,1}, { 1, 0, 1,-1}, { 1, 0,-1,1}, { 1, 0,-1,-1},
883 {-1, 0,1,1}, {-1, 0, 1,-1}, {-1, 0,-1,1}, {-1, 0,-1,-1},
884 { 1, 1,0,1}, { 1, 1, 0,-1}, { 1,-1, 0,1}, { 1,-1, 0,-1},
885 {-1, 1,0,1}, {-1, 1, 0,-1}, {-1,-1, 0,1}, {-1,-1, 0,-1},
886 { 1, 1,1,0}, { 1, 1,-1, 0}, { 1,-1, 1,0}, { 1,-1,-1, 0},
887 {-1, 1,1,0}, {-1, 1,-1, 0}, {-1,-1, 1,0}, {-1,-1,-1, 0}};
892 pixels = (
char*)malloc( 256*256*4 );
893 for(i = 0; i<256; i++)
894 for(j = 0; j<256; j++) {
895 int offset = (i*256+j)*4;
896 char value =
perm[(j+
perm[i]) & 0xFF];
897 pixels[offset+2] = grad4[value & 0x1F][0] * 64 + 64;
898 pixels[offset+1] = grad4[value & 0x1F][1] * 64 + 64;
899 pixels[offset+0] = grad4[value & 0x1F][2] * 64 + 64;
900 pixels[offset+3] = grad4[value & 0x1F][3] * 64 + 64;
903 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels );
904 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
905 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
906 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
907 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
944 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
948 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
956 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
958 bool alreadyActiveOnThisContext =
false;
964 if (i->second == program->program.programName)
965 alreadyActiveOnThisContext =
true;
967 i->second = program->program.programName;
974 if (!alreadyActiveOnThisContext)
978 glValidateProgram(program->program.programName);
980 int infologLength = 0;
981 glGetProgramiv(program->program.programName, GL_INFO_LOG_LENGTH, &infologLength);
982 if (infologLength > 0)
984 char *infoLog = (
char *)malloc(infologLength);
985 int charsWritten = 0;
986 glGetProgramInfoLog(program->program.programName, infologLength, &charsWritten, infoLog);
992 glUseProgram(program->program.programName);
995 GLuint textureUnit = 0;
996 bool explicitColorBuffer =
false;
997 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
1002 if (strncmp(uniform.type,
"VuoList_", 8) == 0)
1007 VDebugLog(
"Warning: Shader '%s' has a value for '%s', but the linked program has no uniform by that name.", shader->
name, uniform.name);
1012 if (strcmp(uniform.type,
"VuoList_VuoBoolean") == 0)
1016 GLint *itemDataGL = (GLint *)malloc(
sizeof(GLint) * itemCount);
1017 for (
size_t i = 0; i < itemCount; ++i)
1018 itemDataGL[i] = itemData[i];
1019 glUniform1iv(location, itemCount, itemDataGL);
1021 else if (strcmp(uniform.type,
"VuoList_VuoInteger") == 0)
1025 GLint *itemDataGL = (GLint *)malloc(
sizeof(GLint) * itemCount);
1026 for (
size_t i = 0; i < itemCount; ++i)
1027 itemDataGL[i] = itemData[i];
1028 glUniform1iv(location, itemCount, itemDataGL);
1030 else if (strcmp(uniform.type,
"VuoList_VuoReal") == 0)
1034 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount);
1035 for (
size_t i = 0; i < itemCount; ++i)
1036 itemDataGL[i] = itemData[i];
1037 glUniform1fv(location, itemCount, itemDataGL);
1039 else if (strcmp(uniform.type,
"VuoList_VuoPoint2d") == 0)
1043 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 2);
1044 for (
size_t i = 0; i < itemCount; ++i)
1046 itemDataGL[i*2 + 0] = itemData[i].x;
1047 itemDataGL[i*2 + 1] = itemData[i].y;
1049 glUniform2fv(location, itemCount, itemDataGL);
1051 else if (strcmp(uniform.type,
"VuoList_VuoPoint3d") == 0)
1055 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 3);
1056 for (
size_t i = 0; i < itemCount; ++i)
1058 itemDataGL[i*3 + 0] = itemData[i].x;
1059 itemDataGL[i*3 + 1] = itemData[i].y;
1060 itemDataGL[i*3 + 2] = itemData[i].z;
1062 glUniform3fv(location, itemCount, itemDataGL);
1064 else if (strcmp(uniform.type,
"VuoList_VuoPoint4d") == 0)
1068 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 4);
1069 for (
size_t i = 0; i < itemCount; ++i)
1071 itemDataGL[i*4 + 0] = itemData[i].x;
1072 itemDataGL[i*4 + 1] = itemData[i].y;
1073 itemDataGL[i*4 + 2] = itemData[i].z;
1074 itemDataGL[i*4 + 3] = itemData[i].w;
1076 glUniform4fv(location, itemCount, itemDataGL);
1078 else if (strcmp(uniform.type,
"VuoList_VuoColor") == 0)
1082 GLfloat *itemDataGL = (GLfloat *)malloc(
sizeof(GLfloat) * itemCount * 4);
1083 for (
size_t i = 0; i < itemCount; ++i)
1085 itemDataGL[i*4 + 0] = itemData[i].r;
1086 itemDataGL[i*4 + 1] = itemData[i].g;
1087 itemDataGL[i*4 + 2] = itemData[i].b;
1088 itemDataGL[i*4 + 3] = itemData[i].a;
1090 glUniform4fv(location, itemCount, itemDataGL);
1093 VDebugLog(
"Warning: Shader '%s' has unknown type '%s' for uniform '%s'.", shader->
name, uniform.type, uniform.name);
1096 if (listLengthUniform != -1)
1097 glUniform1i(listLengthUniform, itemCount);
1104 if (strcmp(uniform.type,
"VuoImage") == 0 && uniform.value.image)
1106 VuoImage image = uniform.value.image;
1110 if (imgRectUniform != -1)
1113 glUniform4f(imgRectUniform, 0, 0, 1, 1);
1119 if (imgSizeUniform != -1)
1124 if (flipUniform != -1)
1125 glUniform1i(flipUniform, 0);
1131 VDebugLog(
"Warning: Shader '%s' has a value for '%s', but the linked program has no uniform by that name.", shader->
name, uniform.name);
1135 if (strcmp(uniform.type,
"VuoImage") == 0)
1137 VuoImage image = uniform.value.image;
1139 glActiveTexture(GL_TEXTURE0 + textureUnit);
1149 glBindTexture(GL_TEXTURE_2D, 0);
1150 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
1152 glUniform1i(location, textureUnit);
1155 if (strcmp(uniform.name,
"colorBuffer") == 0)
1156 explicitColorBuffer =
true;
1158 else if (strcmp(uniform.type,
"VuoBoolean") == 0)
1159 glUniform1i(location, uniform.value.boolean);
1160 else if (strcmp(uniform.type,
"VuoInteger") == 0)
1161 glUniform1i(location, uniform.value.integer);
1162 else if (strcmp(uniform.type,
"VuoReal") == 0)
1163 glUniform1f(location, uniform.value.real);
1164 else if (strcmp(uniform.type,
"VuoPoint2d") == 0)
1165 glUniform2f(location, uniform.value.point2d.x, uniform.value.point2d.y);
1166 else if (strcmp(uniform.type,
"VuoPoint3d") == 0)
1167 glUniform3f(location, uniform.value.point3d.x, uniform.value.point3d.y, uniform.value.point3d.z);
1168 else if (strcmp(uniform.type,
"VuoPoint4d") == 0)
1169 glUniform4f(location, uniform.value.point4d.x, uniform.value.point4d.y, uniform.value.point4d.z, uniform.value.point4d.w);
1170 else if (strcmp(uniform.type,
"VuoColor") == 0)
1171 glUniform4f(location, uniform.value.color.r, uniform.value.color.g, uniform.value.color.b, uniform.value.color.a);
1172 else if (strcmp(uniform.type,
"mat2") == 0)
1173 glUniformMatrix2fv(location, 1, GL_FALSE, uniform.value.mat2);
1174 else if (strcmp(uniform.type,
"mat3") == 0)
1175 glUniformMatrix3fv(location, 1, GL_FALSE, uniform.value.mat3);
1176 else if (strcmp(uniform.type,
"mat4") == 0)
1177 glUniformMatrix4fv(location, 1, GL_FALSE, uniform.value.mat4);
1179 VUserLog(
"Error: Unknown type %s for '%s'", uniform.type, uniform.name);
1184 if (perlinTextureUniform != -1)
1186 glActiveTexture(GL_TEXTURE0 + textureUnit);
1188 static dispatch_once_t initPerlinTexture = 0;
1189 dispatch_once(&initPerlinTexture, ^{
1194 glUniform1i(perlinTextureUniform, textureUnit);
1199 if (gradTextureUniform != -1)
1201 glActiveTexture(GL_TEXTURE0 + textureUnit);
1203 static dispatch_once_t initGradTexture = 0;
1204 dispatch_once(&initGradTexture, ^{
1209 glUniform1i(gradTextureUniform, textureUnit);
1217 GLint width, height;
1218 if ((!explicitColorBuffer && colorBufferUniform != -1) || depthBufferUniform != -1)
1221 glGetIntegerv(GL_VIEWPORT, viewport);
1222 width = viewport[2];
1223 height = viewport[3];
1226 if (!explicitColorBuffer && colorBufferUniform != -1)
1229 glActiveTexture(GL_TEXTURE0 + textureUnit);
1231 GLuint colorBufferTexture =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_RGBA, width, height, GL_BGRA, NULL);
1232 glBindTexture(GL_TEXTURE_2D, colorBufferTexture);
1234 GLint multisampling, multisampledFramebuffer;
1235 glGetIntegerv(GL_SAMPLE_BUFFERS, &multisampling);
1236 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &multisampledFramebuffer);
1237 if (multisampling && multisampledFramebuffer)
1239 GLuint resolvedFramebuffer;
1240 glGenFramebuffers(1, &resolvedFramebuffer);
1241 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFramebuffer);
1244 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTexture, 0);
1246 glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, multisampledFramebuffer);
1247 glReadBuffer(GL_COLOR_ATTACHMENT0);
1248 glDrawBuffer(GL_COLOR_ATTACHMENT0);
1249 glBlitFramebuffer(0, 0, width, height,
1250 0, 0, width, height,
1251 GL_COLOR_BUFFER_BIT,
1254 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1257 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, multisampledFramebuffer);
1258 glDeleteFramebuffers(1, &resolvedFramebuffer);
1261 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);
1266 glUniform1i(colorBufferUniform, textureUnit);
1270 if (depthBufferUniform != -1)
1273 glActiveTexture(GL_TEXTURE0 + textureUnit);
1275 GLuint depthBufferTexture =
VuoGlTexturePool_use(cgl_ctx, VuoGlTexturePool_Allocate, GL_TEXTURE_2D, GL_DEPTH_COMPONENT16, width, height, GL_DEPTH_COMPONENT, NULL);
1276 glBindTexture(GL_TEXTURE_2D, depthBufferTexture);
1279 glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, 0, width, height, 0);
1284 glUniform1i(depthBufferUniform, textureUnit);
1295 if (timedeltaUniform != -1)
1300 if (dateUniform != -1)
1309 glUniform4f(dateUniform, (
float)year, (
float)month, (
float)dayOfMonth, (
float)(second + (minute + (hour * 60)) * 60));
1313 if (frameindexUniform != -1)
1320 *outputProgram = program->program;
1351 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1353 GLuint textureUnit = 0;
1354 for (
unsigned int i = 0; i < shader->uniformsCount; ++i)
1360 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0)
1362 VuoImage image = shader->uniforms[i].value.image;
1366 glActiveTexture(GL_TEXTURE0 + textureUnit);
1374 glActiveTexture(GL_TEXTURE0 + textureUnit);
1375 glBindTexture(GL_TEXTURE_2D, 0);
1381 glActiveTexture(GL_TEXTURE0 + textureUnit);
1382 glBindTexture(GL_TEXTURE_2D, 0);
1388 glActiveTexture(GL_TEXTURE0 + textureUnit);
1389 glBindTexture(GL_TEXTURE_2D, 0);
1397 glActiveTexture(GL_TEXTURE0 + textureUnit);
1398 glBindTexture(GL_TEXTURE_2D, 0);
1408 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);
1424 CGLContextObj cgl_ctx = (CGLContextObj)glContext;
1442 if (json_object_object_get_ex(js,
"pointer", &o))
1443 return (
VuoShader)json_object_get_int64(o);
1461 json_object_object_add(js,
"pointer", json_object_new_int64((int64_t)value));
1483 return strdup(
"No shader");
1485 return strdup(value->
name);
1502 VuoPoint2d samplerCoordinates;
1505 return samplerCoordinates;
1563 dispatch_semaphore_wait((dispatch_semaphore_t)shader->
lock, DISPATCH_TIME_FOREVER);
1565 for (
int i = 0; i < shader->uniformsCount; ++i)
1567 if (strcmp(shader->uniforms[i].type,
"VuoColor") == 0
1575 if (strcmp(shader->uniforms[i].type,
"VuoList_VuoColor") == 0
1583 if (strcmp(shader->uniforms[i].type,
"VuoReal") == 0
1584 && strcmp(shader->uniforms[i].name,
"alpha") == 0
1585 && shader->uniforms[i].value.real < 1)
1592 if (strcmp(shader->uniforms[i].type,
"VuoImage") == 0
1593 && shader->uniforms[i].value.image
1603 dispatch_semaphore_signal((dispatch_semaphore_t)shader->
lock);