in Frameworks/OpenGLES/GLES1122/OpenGLES20/ShaderProgram.mm [60:502]
GLuint ShaderProgram::createProgram(Shader* vertexShader, Shader* fragmentShader) {
GLuint vertexShaderId = vertexShader->compile();
GLuint fragmentShaderId = fragmentShader->compile();
glReleaseShaderCompiler();
GLuint program = glCreateProgram();
if (program == 0) {
LOG_MESSAGE(__FILE__, __LINE__, OpenGLESString("ERROR: Creating program ") + name + " failed.");
return 0;
}
glAttachShader(program, vertexShaderId);
glAttachShader(program, fragmentShaderId);
#ifdef WINPHONE
glLinkProgram(program);
#else
glLinkProgram(program);
#endif
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if (!linked || OpenGLESConfig::DEBUG) {
GLint infoLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLength);
if (infoLength > 1) {
char* infoLog = (char*)malloc(sizeof(char) * infoLength);
glGetProgramInfoLog(program, infoLength, NULL, infoLog);
TraceError(TAG, L"Error compiling %hs", infoLog);
if (linked) {
LOG_MESSAGE(__FILE__, __LINE__, OpenGLESString("WARNING: Linked program ") + name + " with warnings:\n" + infoLog);
} else {
LOG_MESSAGE(__FILE__, __LINE__, OpenGLESString("ERROR: Linking program ") + name + " failed:\n" + infoLog);
}
free(infoLog);
}
if (linked != 0) {
LOG_MESSAGE(OpenGLESString("Linked program ") + name + " successfully.");
} else {
glDeleteProgram(program);
return 0;
}
}
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes);
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttributesMaxLength);
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms);
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformsMaxLength);
glGetProgramiv(program, GL_ATTACHED_SHADERS, &attachedShaders);
LOG_DEBUG_MESSAGE(OpenGLESString("Active attributes: ") + activeAttributes);
LOG_DEBUG_MESSAGE(OpenGLESString("Active attributes max length: ") + activeAttributesMaxLength);
LOG_DEBUG_MESSAGE(OpenGLESString("Active uniforms: ") + activeUniforms);
LOG_DEBUG_MESSAGE(OpenGLESString("Active uniforms max length: ") + activeUniformsMaxLength);
LOG_DEBUG_MESSAGE(OpenGLESString("Attached shaders: ") + attachedShaders);
LOG_DEBUG_MESSAGE("Attributes");
for (int i = 0; i < activeAttributes; i++) {
auto attributeNameBuffer = std::make_unique<char[]>(activeAttributesMaxLength);
char* attributeName = attributeNameBuffer.get();
GLint size;
GLenum type;
glGetActiveAttrib(program, i, activeAttributesMaxLength, NULL, &size, &type, attributeName);
GLint attributeLocation = glGetAttribLocation(program, attributeName);
int id = -1;
if (strcmp(attributeName, "a_position") == 0) {
id = AttributeId::POSITION;
} else if (strcmp(attributeName, "a_normal") == 0) {
id = AttributeId::NORMAL;
} else if (strcmp(attributeName, "a_color") == 0) {
id = AttributeId::COLOR;
} else if (strcmp(attributeName, "a_texCoord0") == 0) {
id = AttributeId::TEXCOORD0;
} else if (strcmp(attributeName, "a_texCoord1") == 0) {
id = AttributeId::TEXCOORD1;
} else if (strcmp(attributeName, "a_texCoord2") == 0) {
id = AttributeId::TEXCOORD2;
} else {
LOG_MESSAGE(__FILE__, __LINE__, OpenGLESString("ERROR: Missing ") + attributeName);
return 0;
}
attributes.push_back(new AttributeSimple(id, attributeLocation));
#ifdef OPENGLES_DEBUG
std::string typeString;
switch (type) {
case GL_FLOAT:
typeString = "GL_FLOAT";
break;
case GL_FLOAT_VEC2:
typeString = "GL_FLOAT_VEC2";
break;
case GL_FLOAT_VEC3:
typeString = "GL_FLOAT_VEC3";
break;
case GL_FLOAT_VEC4:
typeString = "GL_FLOAT_VEC4";
break;
case GL_FLOAT_MAT2:
typeString = "GL_FLOAT_MAT2";
break;
case GL_FLOAT_MAT3:
typeString = "GL_FLOAT_MAT3";
break;
case GL_FLOAT_MAT4:
typeString = "GL_FLOAT_MAT4";
break;
default:
typeString = "Unknown";
LOG_DEBUG_MESSAGE(__FILE__, __LINE__, "ERROR: Unknown type.");
break;
}
LOG_DEBUG_MESSAGE(OpenGLESString(attributeName) + ": type " + typeString + " location: " + attributeLocation);
#endif
}
LOG_DEBUG_MESSAGE("Uniforms");
for (int i = 0; i < activeUniforms; i++) {
auto uniformNameBuffer = std::make_unique<char[]>(activeUniformsMaxLength);
char* uniformName = uniformNameBuffer.get();
GLint size;
GLenum uniformType;
glGetActiveUniform(program, i, activeUniformsMaxLength, NULL, &size, &uniformType, uniformName);
GLint uniformLocation = glGetUniformLocation(program, uniformName);
int id = -1;
if (strcmp(uniformName, "u_lightModelLocalViewerEnabled") == 0) {
id = UniformId::LIGHT_MODEL_LOCAL_VIEWER_ENABLED;
} else if (strcmp(uniformName, "u_lightModelTwoSideEnabled") == 0) {
id = UniformId::LIGHT_MODEL_TWO_SIDE_ENABLED;
} else if (strcmp(uniformName, "u_lightingEnabled") == 0) {
id = UniformId::LIGHTING_ENABLED;
} else if (strcmp(uniformName, "u_light0Enabled") == 0) {
id = UniformId::LIGHT0_ENABLED;
} else if (strcmp(uniformName, "u_light1Enabled") == 0) {
id = UniformId::LIGHT1_ENABLED;
} else if (strcmp(uniformName, "u_light2Enabled") == 0) {
id = UniformId::LIGHT2_ENABLED;
} else if (strcmp(uniformName, "u_light0.ambient") == 0) {
id = UniformId::LIGHT0_AMBIENT;
} else if (strcmp(uniformName, "u_light1.ambient") == 0) {
id = UniformId::LIGHT1_AMBIENT;
} else if (strcmp(uniformName, "u_light2.ambient") == 0) {
id = UniformId::LIGHT2_AMBIENT;
} else if (strcmp(uniformName, "u_light0.diffuse") == 0) {
id = UniformId::LIGHT0_DIFFUSE;
} else if (strcmp(uniformName, "u_light1.diffuse") == 0) {
id = UniformId::LIGHT1_DIFFUSE;
} else if (strcmp(uniformName, "u_light2.diffuse") == 0) {
id = UniformId::LIGHT2_DIFFUSE;
} else if (strcmp(uniformName, "u_light0.specular") == 0) {
id = UniformId::LIGHT0_SPECULAR;
} else if (strcmp(uniformName, "u_light1.specular") == 0) {
id = UniformId::LIGHT1_SPECULAR;
} else if (strcmp(uniformName, "u_light2.specular") == 0) {
id = UniformId::LIGHT2_SPECULAR;
} else if (strcmp(uniformName, "u_light0.position") == 0) {
id = UniformId::LIGHT0_POSITION;
} else if (strcmp(uniformName, "u_light1.position") == 0) {
id = UniformId::LIGHT1_POSITION;
} else if (strcmp(uniformName, "u_light2.position") == 0) {
id = UniformId::LIGHT2_POSITION;
} else if (strcmp(uniformName, "u_light0.spotDirection") == 0) {
id = UniformId::LIGHT0_SPOT_DIRECTION;
} else if (strcmp(uniformName, "u_light1.spotDirection") == 0) {
id = UniformId::LIGHT1_SPOT_DIRECTION;
} else if (strcmp(uniformName, "u_light2.spotDirection") == 0) {
id = UniformId::LIGHT2_SPOT_DIRECTION;
} else if (strcmp(uniformName, "u_light0.spotExponent") == 0) {
id = UniformId::LIGHT0_SPOT_EXPONENT;
} else if (strcmp(uniformName, "u_light1.spotExponent") == 0) {
id = UniformId::LIGHT1_SPOT_EXPONENT;
} else if (strcmp(uniformName, "u_light2.spotExponent") == 0) {
id = UniformId::LIGHT2_SPOT_EXPONENT;
} else if (strcmp(uniformName, "u_light0.spotCutoffAngleCos") == 0) {
id = UniformId::LIGHT0_SPOT_CUTOFF_ANGLE_COS;
} else if (strcmp(uniformName, "u_light1.spotCutoffAngleCos") == 0) {
id = UniformId::LIGHT1_SPOT_CUTOFF_ANGLE_COS;
} else if (strcmp(uniformName, "u_light2.spotCutoffAngleCos") == 0) {
id = UniformId::LIGHT2_SPOT_CUTOFF_ANGLE_COS;
} else if (strcmp(uniformName, "u_light0.constantAttenuation") == 0) {
id = UniformId::LIGHT0_CONSTANT_ATTENUATION;
} else if (strcmp(uniformName, "u_light1.constantAttenuation") == 0) {
id = UniformId::LIGHT1_CONSTANT_ATTENUATION;
} else if (strcmp(uniformName, "u_light2.constantAttenuation") == 0) {
id = UniformId::LIGHT2_CONSTANT_ATTENUATION;
} else if (strcmp(uniformName, "u_light0.linearAttenuation") == 0) {
id = UniformId::LIGHT0_LINEAR_ATTENUATION;
} else if (strcmp(uniformName, "u_light1.linearAttenuation") == 0) {
id = UniformId::LIGHT1_LINEAR_ATTENUATION;
} else if (strcmp(uniformName, "u_light2.linearAttenuation") == 0) {
id = UniformId::LIGHT2_LINEAR_ATTENUATION;
} else if (strcmp(uniformName, "u_light0.quadraticAttenuation") == 0) {
id = UniformId::LIGHT0_QUADRATIC_ATTENUATION;
} else if (strcmp(uniformName, "u_light1.quadraticAttenuation") == 0) {
id = UniformId::LIGHT1_QUADRATIC_ATTENUATION;
} else if (strcmp(uniformName, "u_light2.quadraticAttenuation") == 0) {
id = UniformId::LIGHT2_QUADRATIC_ATTENUATION;
} else if (strcmp(uniformName, "u_modelViewMatrix") == 0) {
id = UniformId::MODELVIEW_MATRIX;
} else if (strcmp(uniformName, "u_modelViewProjectionMatrix") == 0) {
id = UniformId::MODELVIEW_PROJECTION_MATRIX;
} else if (strcmp(uniformName, "u_transposeAdjointModelViewMatrix") == 0) {
id = UniformId::TRANPOSE_ADJOINT_MODEL_VIEW_MATRIX;
} else if (strcmp(uniformName, "u_rescaleNormalFactor") == 0) {
id = UniformId::RESCALE_NORMAL_FACTOR;
} else if (strcmp(uniformName, "u_material.ambient") == 0) {
id = UniformId::MATERIAL_AMBIENT;
} else if (strcmp(uniformName, "u_material.diffuse") == 0) {
id = UniformId::MATERIAL_DIFFUSE;
} else if (strcmp(uniformName, "u_material.specular") == 0) {
id = UniformId::MATERIAL_SPECULAR;
} else if (strcmp(uniformName, "u_material.emission") == 0) {
id = UniformId::MATERIAL_EMISSION;
} else if (strcmp(uniformName, "u_material.shininess") == 0) {
id = UniformId::MATERIAL_SHININESS;
} else if (strcmp(uniformName, "u_normalizeEnabled") == 0) {
id = UniformId::NORMALIZE_ENABLED;
} else if (strcmp(uniformName, "u_rescaleNormalEnabled") == 0) {
id = UniformId::RESCALE_NORMAL_ENABLED;
} else if (strcmp(uniformName, "u_alphaTestEnabled") == 0) {
id = UniformId::ALPHA_TEST_ENABLED;
} else if (strcmp(uniformName, "u_alphaFunc") == 0) {
id = UniformId::ALPHA_FUNC;
} else if (strcmp(uniformName, "u_alphaFuncValue") == 0) {
id = UniformId::ALPHA_FUNC_VALUE;
} else if (strcmp(uniformName, "u_globalAmbientColor") == 0) {
id = UniformId::GLOBAL_AMBIENT_COLOR;
} else if (strcmp(uniformName, "u_globalColor") == 0) {
id = UniformId::GLOBAL_COLOR;
} else if (strcmp(uniformName, "u_positionEnabled") == 0) {
id = UniformId::POSITION_ENABLED;
} else if (strcmp(uniformName, "u_normalEnabled") == 0) {
id = UniformId::NORMAL_ENABLED;
} else if (strcmp(uniformName, "u_colorEnabled") == 0) {
id = UniformId::COLOR_ENABLED;
} else if (strcmp(uniformName, "u_texCoord0Enabled") == 0) {
id = UniformId::TEXCOORD0_ENABLED;
} else if (strcmp(uniformName, "u_texCoord1Enabled") == 0) {
id = UniformId::TEXCOORD1_ENABLED;
} else if (strcmp(uniformName, "u_texCoord2Enabled") == 0) {
id = UniformId::TEXCOORD2_ENABLED;
} else if (strcmp(uniformName, "u_texture0Enabled") == 0) {
id = UniformId::TEXTURE0_ENABLED;
} else if (strcmp(uniformName, "u_texture1Enabled") == 0) {
id = UniformId::TEXTURE1_ENABLED;
} else if (strcmp(uniformName, "u_texture2Enabled") == 0) {
id = UniformId::TEXTURE2_ENABLED;
} else if (strcmp(uniformName, "u_texture0Sampler") == 0) {
id = UniformId::TEXTURE0_SAMPLER;
} else if (strcmp(uniformName, "u_texture1Sampler") == 0) {
id = UniformId::TEXTURE1_SAMPLER;
} else if (strcmp(uniformName, "u_texture2Sampler") == 0) {
id = UniformId::TEXTURE2_SAMPLER;
} else if (strcmp(uniformName, "u_texture0Matrix") == 0) {
id = UniformId::TEXTURE0_MATRIX;
} else if (strcmp(uniformName, "u_texture1Matrix") == 0) {
id = UniformId::TEXTURE1_MATRIX;
} else if (strcmp(uniformName, "u_texture2Matrix") == 0) {
id = UniformId::TEXTURE2_MATRIX;
} else if (strcmp(uniformName, "u_texture0MatrixEnabled") == 0) {
id = UniformId::TEXTURE0_MATRIX_ENABLED;
} else if (strcmp(uniformName, "u_texture1MatrixEnabled") == 0) {
id = UniformId::TEXTURE1_MATRIX_ENABLED;
} else if (strcmp(uniformName, "u_texture2MatrixEnabled") == 0) {
id = UniformId::TEXTURE2_MATRIX_ENABLED;
} else if (strcmp(uniformName, "u_texture0Format") == 0) {
id = UniformId::TEXTURE0_FORMAT;
} else if (strcmp(uniformName, "u_texture1Format") == 0) {
id = UniformId::TEXTURE1_FORMAT;
} else if (strcmp(uniformName, "u_texture2Format") == 0) {
id = UniformId::TEXTURE2_FORMAT;
} else if (strcmp(uniformName, "u_texture0EnvMode") == 0) {
id = UniformId::TEXTURE0_ENV_MODE;
} else if (strcmp(uniformName, "u_texture1EnvMode") == 0) {
id = UniformId::TEXTURE1_ENV_MODE;
} else if (strcmp(uniformName, "u_texture2EnvMode") == 0) {
id = UniformId::TEXTURE2_ENV_MODE;
} else if (strcmp(uniformName, "u_texture0EnvColor") == 0) {
id = UniformId::TEXTURE0_ENV_COLOR;
} else if (strcmp(uniformName, "u_texture1EnvColor") == 0) {
id = UniformId::TEXTURE1_ENV_COLOR;
} else if (strcmp(uniformName, "u_texture2EnvColor") == 0) {
id = UniformId::TEXTURE2_ENV_COLOR;
} else if (strcmp(uniformName, "u_texture0EnvRGBScale") == 0) {
id = UniformId::TEXTURE0_ENV_RGB_SCALE;
} else if (strcmp(uniformName, "u_texture1EnvRGBScale") == 0) {
id = UniformId::TEXTURE1_ENV_RGB_SCALE;
} else if (strcmp(uniformName, "u_texture2EnvRGBScale") == 0) {
id = UniformId::TEXTURE2_ENV_RGB_SCALE;
} else if (strcmp(uniformName, "u_texture0EnvAlphaScale") == 0) {
id = UniformId::TEXTURE0_ENV_ALPHA_SCALE;
} else if (strcmp(uniformName, "u_texture1EnvAlphaScale") == 0) {
id = UniformId::TEXTURE1_ENV_ALPHA_SCALE;
} else if (strcmp(uniformName, "u_texture2EnvAlphaScale") == 0) {
id = UniformId::TEXTURE2_ENV_ALPHA_SCALE;
} else if (strcmp(uniformName, "u_texture0EnvBlurAmount") == 0) {
id = UniformId::TEXTURE0_ENV_BLUR_AMOUNT;
} else if (strcmp(uniformName, "u_texture1EnvBlurAmount") == 0) {
id = UniformId::TEXTURE1_ENV_BLUR_AMOUNT;
} else if (strcmp(uniformName, "u_texture2EnvBlurAmount") == 0) {
id = UniformId::TEXTURE2_ENV_BLUR_AMOUNT;
} else if (strcmp(uniformName, "u_texture0EnvCombineRGB") == 0) {
id = UniformId::TEXTURE0_ENV_COMBINE_RGB;
} else if (strcmp(uniformName, "u_texture1EnvCombineRGB") == 0) {
id = UniformId::TEXTURE1_ENV_COMBINE_RGB;
} else if (strcmp(uniformName, "u_texture2EnvCombineRGB") == 0) {
id = UniformId::TEXTURE2_ENV_COMBINE_RGB;
} else if (strcmp(uniformName, "u_texture0EnvCombineAlpha") == 0) {
id = UniformId::TEXTURE0_ENV_COMBINE_ALPHA;
} else if (strcmp(uniformName, "u_texture1EnvCombineAlpha") == 0) {
id = UniformId::TEXTURE1_ENV_COMBINE_ALPHA;
} else if (strcmp(uniformName, "u_texture2EnvCombineAlpha") == 0) {
id = UniformId::TEXTURE2_ENV_COMBINE_ALPHA;
} else if (strcmp(uniformName, "u_fogEnabled") == 0) {
id = UniformId::FOG_ENABLED;
} else if (strcmp(uniformName, "u_fogColor") == 0) {
id = UniformId::FOG_COLOR;
} else if (strcmp(uniformName, "u_fogMode") == 0) {
id = UniformId::FOG_MODE;
} else if (strcmp(uniformName, "u_fogDensity") == 0) {
id = UniformId::FOG_DENSITY;
} else if (strcmp(uniformName, "u_fogStart") == 0) {
id = UniformId::FOG_START;
} else if (strcmp(uniformName, "u_fogEnd") == 0) {
id = UniformId::FOG_END;
} else if (strcmp(uniformName, "u_fogHint") == 0) {
id = UniformId::FOG_HINT;
} else if (strcmp(uniformName, "u_lightingHint") == 0) {
id = UniformId::LIGHTING_HINT;
} else if (strcmp(uniformName, "u_clipPlane0Enabled") == 0) {
id = UniformId::CLIP_PLANE0_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane1Enabled") == 0) {
id = UniformId::CLIP_PLANE1_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane2Enabled") == 0) {
id = UniformId::CLIP_PLANE2_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane3Enabled") == 0) {
id = UniformId::CLIP_PLANE3_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane4Enabled") == 0) {
id = UniformId::CLIP_PLANE4_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane5Enabled") == 0) {
id = UniformId::CLIP_PLANE5_ENABLED;
} else if (strcmp(uniformName, "u_clipPlane0Equation") == 0) {
id = UniformId::CLIP_PLANE0_EQUATION;
} else if (strcmp(uniformName, "u_clipPlane1Equation") == 0) {
id = UniformId::CLIP_PLANE1_EQUATION;
} else if (strcmp(uniformName, "u_clipPlane2Equation") == 0) {
id = UniformId::CLIP_PLANE2_EQUATION;
} else if (strcmp(uniformName, "u_clipPlane3Equation") == 0) {
id = UniformId::CLIP_PLANE3_EQUATION;
} else if (strcmp(uniformName, "u_clipPlane4Equation") == 0) {
id = UniformId::CLIP_PLANE4_EQUATION;
} else if (strcmp(uniformName, "u_clipPlane5Equation") == 0) {
id = UniformId::CLIP_PLANE5_EQUATION;
} else {
LOG_MESSAGE(__FILE__, __LINE__, OpenGLESString("ERROR: Missing ") + uniformName);
return 0;
}
uniforms.push_back(new UniformSimple(id, uniformLocation));
#ifdef OPENGLES_DEBUG
std::string typeString;
switch (uniformType) {
case GL_FLOAT:
typeString = "GL_FLOAT";
break;
case GL_FLOAT_VEC2:
typeString = "GL_FLOAT_VEC2";
break;
case GL_FLOAT_VEC3:
typeString = "GL_FLOAT_VEC3";
break;
case GL_FLOAT_VEC4:
typeString = "GL_FLOAT_VEC4";
break;
case GL_INT:
typeString = "GL_INT";
break;
case GL_INT_VEC2:
typeString = "GL_INT_VEC2";
break;
case GL_INT_VEC3:
typeString = "GL_INT_VEC3";
break;
case GL_INT_VEC4:
typeString = "GL_INT_VEC4";
break;
case GL_BOOL:
typeString = "GL_BOOL";
break;
case GL_BOOL_VEC2:
typeString = "GL_BOOL_VEC2";
break;
case GL_BOOL_VEC3:
typeString = "GL_BOOL_VEC3";
break;
case GL_BOOL_VEC4:
typeString = "GL_BOOL_VEC4";
break;
case GL_FLOAT_MAT2:
typeString = "GL_FLOAT_MAT2";
break;
case GL_FLOAT_MAT3:
typeString = "GL_FLOAT_MAT3";
break;
case GL_FLOAT_MAT4:
typeString = "GL_FLOAT_MAT4";
break;
case GL_SAMPLER_2D:
typeString = "GL_SAMPLER_2D";
break;
case GL_SAMPLER_CUBE:
typeString = "GL_SAMPLER_CUBE";
break;
default:
typeString = "Unknown";
LOG_DEBUG_MESSAGE(__FILE__, __LINE__, OpenGLESString("ERROR: Unknown type ") + uniformType);
break;
}
LOG_DEBUG_MESSAGE(OpenGLESString(uniformName) + ": type " + typeString + " location: " + uniformLocation);
#endif
}
LOG_DEBUG_MESSAGE("\n");
return program;
}