uint32_t cShaderObject::GetSubroutineIndex(eShaderType type, cStringRef name) { uint32_t ret = glGetSubroutineUniformLocation( mShaderProgram, GLShaderType(type), name.data()); AKJ_ASSERT_AND_THROW(ret != GL_INVALID_INDEX); return ret; }
void GLProgram::getActiveSubroutineUniforms(std::vector<GLSLSubroutineUniform>& list, GLenum shaderType) const { GLint count; glGetProgramStageiv(_handle, shaderType, GL_ACTIVE_SUBROUTINE_UNIFORMS, &count); GLint biggerNameLength; glGetProgramStageiv(_handle, shaderType, GL_ACTIVE_SUBROUTINE_UNIFORM_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) { glGetActiveSubroutineUniformName(_handle, shaderType, index, biggerNameLength, 0, name); GLint location = glGetSubroutineUniformLocation(_handle, shaderType, name); GLint compatibleSubroutinesCount; glGetActiveSubroutineUniformiv(_handle, shaderType, index, GL_NUM_COMPATIBLE_SUBROUTINES, &compatibleSubroutinesCount); GLint* compatibleSubroutines = new GLint[compatibleSubroutinesCount]; glGetActiveSubroutineUniformiv(_handle, shaderType, index, GL_COMPATIBLE_SUBROUTINES, compatibleSubroutines); // @uniformArraySize is 1 if subroutine uniform is not an array GLint uniformArraySize; glGetActiveSubroutineUniformiv(_handle, shaderType, index, GL_UNIFORM_SIZE, &uniformArraySize); GLSLSubroutineUniform subroutineUniform; subroutineUniform.program = _handle; subroutineUniform.location = location; subroutineUniform.shaderType = shaderType; subroutineUniform.name = name; subroutineUniform.compatibleSubroutines = std::vector<GLint>(compatibleSubroutines, compatibleSubroutines + compatibleSubroutinesCount); subroutineUniform.uniformArraySize = uniformArraySize; list.push_back(subroutineUniform); delete[] compatibleSubroutines; } delete[] name; } }
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 subroutines_app::load_shaders() { GLuint shaders[2]; shaders[0] = sb6::shader::load("media/shaders/subroutines/subroutines.vs.glsl", GL_VERTEX_SHADER); shaders[1] = sb6::shader::load("media/shaders/subroutines/subroutines.fs.glsl", GL_FRAGMENT_SHADER); if (render_program) glDeleteProgram(render_program); render_program = sb6::program::link_from_shaders(shaders, 2, true); subroutines[0] = glGetSubroutineIndex(render_program, GL_FRAGMENT_SHADER, "myFunction1"); subroutines[1] = glGetSubroutineIndex(render_program, GL_FRAGMENT_SHADER, "myFunction2"); uniforms.subroutine1 = glGetSubroutineUniformLocation(render_program, GL_FRAGMENT_SHADER, "mySubroutineUniform"); }
void NGLScene::loadMatricesToShader() { ngl::ShaderLib *shader=ngl::ShaderLib::instance(); ngl::Mat4 MV; ngl::Mat4 MVP; ngl::Mat3 normalMatrix; ngl::Mat4 M; M=m_transformStack.getCurrentTransform().getMatrix(); MV= M*m_mouseGlobalTX*m_cam->getViewMatrix(); MVP=MV*m_cam->getProjectionMatrix() ; normalMatrix=MV; normalMatrix.inverse(); shader->setShaderParamFromMat4("MVP",MVP); shader->setShaderParamFromMat3("normalMatrix",normalMatrix); GLuint m_id=glGetSubroutineUniformLocation(shader->getProgramID("PointLightDiffuse"),GL_FRAGMENT_SHADER,"shadingModelSelection"); std::cout<<m_id<<"\n"; //glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,0); }
bool initProgram() { bool Validated = true; compiler Compiler; if(Validated) { GLuint VertShaderName = Compiler.create(GL_VERTEX_SHADER, getDataDirectory() + VERTEX_SHADER_SOURCE); GLuint FragShaderName = Compiler.create(GL_FRAGMENT_SHADER, getDataDirectory() + FRAGMENT_SHADER_SOURCE); ProgramName = glCreateProgram(); glAttachShader(ProgramName, VertShaderName); glAttachShader(ProgramName, FragShaderName); glLinkProgram(ProgramName); } if(Validated) { Validated = Validated && Compiler.check(); Validated = Validated && Compiler.check_program(ProgramName); } if(Validated) { GLint ProgramVertSubroutine(0); GLint ProgramFragSubroutine(0); glGetProgramStageiv(ProgramName, GL_VERTEX_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &ProgramVertSubroutine); glGetProgramStageiv(ProgramName, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORMS, &ProgramFragSubroutine); UniformMVP = glGetUniformLocation(ProgramName, "MVP"); UniformDXT1 = glGetUniformLocation(ProgramName, "DiffuseDXT1"); UniformRGB8 = glGetUniformLocation(ProgramName, "DiffuseRGB8"); UniformDisplacement = glGetUniformLocation(ProgramName, "Displacement"); UniformDiffuse = glGetSubroutineUniformLocation(ProgramName, GL_FRAGMENT_SHADER, "Diffuse"); IndexDXT1 = glGetSubroutineIndex(ProgramName, GL_FRAGMENT_SHADER, "diffuseLQ"); IndexRGB8 = glGetSubroutineIndex(ProgramName, GL_FRAGMENT_SHADER, "diffuseHQ"); } return Validated; }
void ShaderEffect::SetSubroutineUniforms(uint_t shaderType, SubroutineLink* link, int numLinks) { int maxUniforms; glGetProgramStageiv(mProgram, shaderType, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &maxUniforms); ASSERT(maxUniforms < MAX_SHADER_SUBROUTINES); for(int uniform = 0; uniform < maxUniforms; ++uniform) { if(uniform < numLinks) { SubroutineLink* ci = &link[uniform]; const int uniformIndex = glGetSubroutineUniformLocation(mProgram, shaderType, ci->UniformName); const int functionIndex = glGetSubroutineIndex(mProgram, shaderType, ci->FunctionName); mSubroutineMap[uniformIndex] = functionIndex; } } glUniformSubroutinesuiv(shaderType, maxUniforms, mSubroutineMap); }
void Plane::init_shader() { m_PlaneShader.init(); m_PlaneShader.attach(GL_VERTEX_SHADER, "light.vert"); m_PlaneShader.attach(GL_FRAGMENT_SHADER, "light.frag"); m_PlaneShader.link(); m_PlaneShader.info(); uniform_loc.lightSub[0] = -1; uniform_loc.lightSub[1] = -1; program = m_PlaneShader.getProgram(); uniform_loc.woodTex = glGetUniformLocation(program, "u_WoodTex"); uniform_loc.lightSub[0] = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "Phong"); uniform_loc.lightSub[1] = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "BlinnPhong"); uniform_loc.lightModelSub = glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "lightModelUniform"); uniform_loc.model = glGetUniformLocation(program, "u_Model"); uniform_loc.view = glGetUniformLocation(program, "u_View"); uniform_loc.proj = glGetUniformLocation(program, "u_Proj"); uniform_loc.gamma = glGetUniformLocation(program, "u_Gamma"); uniform_loc.lightPos = glGetUniformLocation(program, "u_LightPos"); uniform_loc.lightColor = glGetUniformLocation(program, "u_LightColor"); uniform_loc.viewPos = glGetUniformLocation(program, "u_ViewPos"); }
bool initProgram() { bool Validated = true; // Create program if(Validated) { GLuint VertexShaderName = glf::createShader(GL_VERTEX_SHADER, glf::DATA_DIRECTORY + VERTEX_SHADER_SOURCE); GLuint FragmentShaderName = glf::createShader(GL_FRAGMENT_SHADER, glf::DATA_DIRECTORY + FRAGMENT_SHADER_SOURCE); Validated = Validated && glf::checkShader(VertexShaderName, VERTEX_SHADER_SOURCE); Validated = Validated && glf::checkShader(FragmentShaderName, FRAGMENT_SHADER_SOURCE); ProgramName = glCreateProgram(); glAttachShader(ProgramName, VertexShaderName); glAttachShader(ProgramName, FragmentShaderName); glDeleteShader(VertexShaderName); glDeleteShader(FragmentShaderName); glLinkProgram(ProgramName); Validated = Validated && glf::checkProgram(ProgramName); } // Get variables locations if(Validated) { UniformMVP = glGetUniformLocation(ProgramName, "MVP"); UniformDXT1 = glGetUniformLocation(ProgramName, "DiffuseDXT1"); UniformRGB8 = glGetUniformLocation(ProgramName, "DiffuseRGB8"); UniformDisplacement = glGetUniformLocation(ProgramName, "Displacement"); UniformDiffuse = glGetSubroutineUniformLocation(ProgramName, GL_FRAGMENT_SHADER, "Diffuse"); IndexDXT1 = glGetSubroutineIndex(ProgramName, GL_FRAGMENT_SHADER, "diffuseLQ"); IndexRGB8 = glGetSubroutineIndex(ProgramName, GL_FRAGMENT_SHADER, "diffuseHQ"); } return Validated && glf::checkError("initProgram"); }
void Graphic::Renderer::ActivateAppropriteToModelSubroutines(const Model& model) const { constexpr unsigned numOfUsedSubroutines = 4; GLuint subroutinesArray[numOfUsedSubroutines]; const ShaderProgram* const shaderProg = GetShaderProgramWithType(ShaderProgram::Type::Main); assert(shaderProg); const GLint shadeSubUniformLoc = glGetSubroutineUniformLocation(shaderProg->id, GL_FRAGMENT_SHADER, "shadeModel"); const GLint toObjectLocalCoordSubUniformLoc = glGetSubroutineUniformLocation(shaderProg->id, GL_FRAGMENT_SHADER, "toObjectLocalCoord"); const GLint getNormalVecSubUniformLoc = glGetSubroutineUniformLocation(shaderProg->id, GL_FRAGMENT_SHADER, "getNormalVec"); const GLint drawObjectSubUniformLoc = glGetSubroutineUniformLocation(shaderProg->id, GL_VERTEX_SHADER, "drawObject"); assert(shadeSubUniformLoc < numOfUsedSubroutines && toObjectLocalCoordSubUniformLoc < numOfUsedSubroutines && getNormalVecSubUniformLoc < numOfUsedSubroutines); #ifdef _DEBUG if ( -1 == shadeSubUniformLoc || -1 == toObjectLocalCoordSubUniformLoc || -1 == getNormalVecSubUniformLoc || -1 == drawObjectSubUniformLoc) { std::cout << "Failed to get subroutines uniform location. \n"; return; } #endif // _DEBUG if (model.material.HasTextureWithType(Texture::Type::Cube)) subroutinesArray[drawObjectSubUniformLoc] = drawObjectSubroutines[1]; else subroutinesArray[drawObjectSubUniformLoc] = drawObjectSubroutines[0]; switch (model.GetType()) { case Model::Type::commonModel: subroutinesArray[shadeSubUniformLoc] = shadeModelSubroutine[0]; //subroutinesArray[shadeSubUniformLoc] = modelSubroutine; break; case Model::Type::lightModel: subroutinesArray[shadeSubUniformLoc] = shadeModelSubroutine[0]; break; case Model::Type::skyBoxModel: //subroutinesArray[shadeSubUniformLoc] = shadeModelSubroutine[2]; break; default: break; } if (model.material.HasTextureWithType(Texture::Type::Normal)) { subroutinesArray[toObjectLocalCoordSubUniformLoc] = normalTextureSubroutines[0]; subroutinesArray[getNormalVecSubUniformLoc] = normalTextureSubroutines[1]; } else { subroutinesArray[toObjectLocalCoordSubUniformLoc] = noNormalTextureSubroutines[0]; subroutinesArray[getNormalVecSubUniformLoc] = noNormalTextureSubroutines[1]; } glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 4, subroutinesArray); }
JNIEXPORT jint JNICALL Java_org_lwjgl_opengl_GL40_nglGetSubroutineUniformLocation(JNIEnv *__env, jclass clazz, jint program, jint shadertype, jlong nameAddress, jlong __functionAddress) { const GLchar *name = (const GLchar *)(intptr_t)nameAddress; glGetSubroutineUniformLocationPROC glGetSubroutineUniformLocation = (glGetSubroutineUniformLocationPROC)(intptr_t)__functionAddress; UNUSED_PARAMS(__env, clazz) return (jint)glGetSubroutineUniformLocation(program, shadertype, name); }