void OGLShaderObject::_initActiveSubroutine() noexcept { #if !defined(EGLAPI) GLint numSubroutines = 0; GLint maxSubroutines = 0; glGetProgramStageiv(_program, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINES, &numSubroutines); glGetProgramStageiv(_program, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_MAX_LENGTH, &maxSubroutines); if (numSubroutines) { auto nameSubroutines = make_scope<GLchar[]>(maxSubroutines + 1); nameSubroutines[maxSubroutines + 1] = 0; for (GLint i = 0; i < maxSubroutines; ++i) { GLenum type = GL_VERTEX_SHADER; glGetActiveSubroutineName(_program, type, i, maxSubroutines, 0, nameSubroutines.get()); GLint location = glGetSubroutineIndex(_program, type, nameSubroutines.get()); auto subroutines = std::make_shared<ShaderSubroutine>(); subroutines->setName(nameSubroutines.get()); subroutines->setLocation(location); _activeSubroutines.push_back(subroutines); } } #endif }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL40_nglGetActiveSubroutineName(JNIEnv *__env, jclass clazz, jint program, jint shadertype, jint index, jint bufsize, jlong lengthAddress, jlong nameAddress, jlong __functionAddress) { GLsizei *length = (GLsizei *)(intptr_t)lengthAddress; GLchar *name = (GLchar *)(intptr_t)nameAddress; glGetActiveSubroutineNamePROC glGetActiveSubroutineName = (glGetActiveSubroutineNamePROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) glGetActiveSubroutineName(program, shadertype, index, bufsize, length, name); }
void GLshader::print_subroutines() { int maxSub,maxSubU,countActiveSU; char name[256]; int len, numCompS; GL_ASSERT(glGetIntegerv(GL_MAX_SUBROUTINES, &maxSub)); GL_ASSERT(glGetIntegerv(GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS, &maxSubU)); printf("Max Subroutines: %d Max Subroutine Uniforms: %d\n", maxSub,maxSubU); GL_ASSERT(glGetProgramStageiv(program, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &countActiveSU)); for (int i = 0; i < countActiveSU; ++i) { glGetActiveSubroutineUniformName(program, GL_VERTEX_SHADER, i, 256, &len, name); printf("Suroutine Uniform: %d name: %s\n", i,name); glGetActiveSubroutineUniformiv(program, GL_VERTEX_SHADER, i, GL_NUM_COMPATIBLE_SUBROUTINES, &numCompS); int *s = (int *) malloc(sizeof(int) * numCompS); glGetActiveSubroutineUniformiv(program, GL_VERTEX_SHADER, i, GL_COMPATIBLE_SUBROUTINES, s); printf("Compatible Subroutines:\n"); for (int j=0; j < numCompS; ++j) { glGetActiveSubroutineName(program, GL_VERTEX_SHADER, s[j], 256, &len, name); printf("\t%d - %s\n", s[j],name); } printf("\n"); free(s); } }
void init(void) { glGenVertexArrays(1, &vao); glBindVertexArray(vao); GLfloat vertices[6][2] = { { -0.90, -0.90 }, // Triangle 1 { 0.85, -0.90 }, { -0.90, 0.85 }, { 0.90, -0.85 }, // Triangle 2 { 0.90, 0.90 }, { -0.85, 0.90 } }; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); h_prog = build_program_from_files("triangles.vert", "sel_func_subroutine_layout.frag"); glUseProgram(h_prog); loc_func = glGetSubroutineUniformLocation(h_prog, GL_FRAGMENT_SHADER, "func"); idx_shader_func[0] = 7; idx_shader_func[1] = 10; printf("location of the uniform subroutine \"func\" = %d\n", loc_func); glGetProgramStageiv(h_prog, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &n_func); printf("# of active subroutine uniforms = %d\n", n_func); GLint n; glGetProgramStageiv(h_prog, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINES, &n); printf("# of active subroutines = %d\n", n); char name[1024]; GLsizei length; glGetActiveSubroutineName(h_prog, GL_FRAGMENT_SHADER, idx_shader_func[0], 1024, &length, name); printf("subroutine name for index %d = %s\n", idx_shader_func[0], name); glGetActiveSubroutineName(h_prog, GL_FRAGMENT_SHADER, idx_shader_func[1], 1024, &length, name); printf("subroutine name for index %d = %s\n", idx_shader_func[1], name); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(0); }
void GLProgram::getActiveSubroutines(std::vector<std::string>& list, GLenum shaderType) const { GLint count; glGetProgramStageiv(_handle, shaderType, GL_ACTIVE_SUBROUTINES, &count); GLint biggerNameLength; glGetProgramStageiv(_handle, shaderType, GL_ACTIVE_SUBROUTINE_MAX_LENGTH, &biggerNameLength); if (count != GL_INVALID_ENUM && biggerNameLength != GL_INVALID_ENUM) { list.reserve(count); GLchar* name = new GLchar[biggerNameLength]; for (GLuint index = 0; index < static_cast<GLuint>(count); ++index) { glGetActiveSubroutineName(_handle, shaderType, index, biggerNameLength, 0, name); list.push_back(std::string(name)); } delete[] name; } }