void ShaderVariableBase::execSyncV( FieldContainer &oFrom, ConstFieldMaskArg whichField, AspectOffsetStore &oOffsets, ConstFieldMaskArg syncMode, const UInt32 uiSyncInfo) { ShaderVariable *pThis = static_cast<ShaderVariable *>(this); pThis->execSync(static_cast<ShaderVariable *>(&oFrom), whichField, oOffsets, syncMode, uiSyncInfo); }
void ShaderExecutableChunk::updateProceduralVariables( DrawEnv *pEnv, UInt32 uiUpdateDependents) { UInt32 uiProgram = pEnv->getActiveShader(); if(uiProgram == 0) return; const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL; if(_sfVariables.getValue() != NULL) { pMFVars = _sfVariables.getValue()->getMFProceduralVariables(); } if(pMFVars == NULL || pMFVars->size() == 0) { return; } MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations(); OSG_ASSERT(pMFVars->size() == vVarLocations.size()); MFInt32::iterator mLocIt = vVarLocations.begin(); ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt = pMFVars->begin(); ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd = pMFVars->end (); #ifdef OSG_1_COMPATX if(_fParameterCallback) { OSGGETGLFUNC(OSGglGetUniformLocationProc, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation()); _fParameterCallback(osgGlGetUniformLocation, pEnv, uiProgram); } #endif for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt) { ShaderVariable *pVar = *mVarIt; switch(pVar->getTypeId()) { case ShaderVariable::SHVTypeOSG: { ShaderVariableOSG *p = dynamic_cast<ShaderVariableOSG *>(pVar); if(0x0000 == (p->getDependency() & uiUpdateDependents)) continue; if(*mLocIt == -1) { OSGGETGLFUNC(OSGglGetUniformLocationProc, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation()); *mLocIt = osgGlGetUniformLocation(uiProgram, p->getName().c_str()); } p->evaluate(pEnv, *mLocIt); } break; case ShaderVariable::SHVTypeFunctor: { ShaderVariableFunctor *p = dynamic_cast<ShaderVariableFunctor *>(pVar); if(0x0000 == (p->getDependency() & uiUpdateDependents)) continue; if(*mLocIt == -1) { OSGGETGLFUNC(OSGglGetUniformLocationProc, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation()); *mLocIt = osgGlGetUniformLocation(uiProgram, p->getName().c_str()); } #ifdef OSG_1_COMPAT switch(p->getFuncMode()) { case 0: { p->evaluate(pEnv, *mLocIt); } break; case 1: { OSGGETGLFUNC( OSGglGetUniformLocationProc, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation()); p->evaluate(osgGlGetUniformLocation, pEnv, uiProgram); } break; case 2: { p->evaluate(p, pEnv, uiProgram); } break; } #else p->evaluate(pEnv, *mLocIt); #endif } break; default: break; } } }
void ComputeShaderChunk::updateProceduralVariables( DrawEnv *pEnv, UInt32 uiUpdateDependents) { UInt32 uiProgram = pEnv->getActiveShader(); if(uiProgram == 0) return; const ShaderProgramVariables::MFProceduralVariablesType *pMFVars = NULL; if(_sfVariables.getValue() != NULL) { pMFVars = _sfVariables.getValue()->getMFProceduralVariables(); } if(pMFVars == NULL || pMFVars->size() == 0) { return; } MFInt32 &vVarLocations = *this->editMFProceduralVariableLocations(); OSG_ASSERT(pMFVars->size() == vVarLocations.size()); MFInt32::iterator mLocIt = vVarLocations.begin(); ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarIt = pMFVars->begin(); ShaderProgramVariables::MFProceduralVariablesType::const_iterator mVarEnd = pMFVars->end (); Window *pWin = pEnv->getWindow(); osgSinkUnusedWarning(pWin); for(; mVarIt != mVarEnd; ++mVarIt, ++mLocIt) { ShaderVariable *pVar = *mVarIt; switch(pVar->getTypeId()) { case ShaderVariable::SHVTypeOSG: { ShaderVariableOSG *p = dynamic_cast<ShaderVariableOSG *>(pVar); if(0x0000 == (p->getDependency() & uiUpdateDependents)) continue; if(*mLocIt == -1) { OSGGETGLFUNCBYID_GL3_ES( glGetUniformLocation, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation(), pWin); *mLocIt = osgGlGetUniformLocation(uiProgram, p->getName().c_str()); } p->evaluate(pEnv, *mLocIt); } break; case ShaderVariable::SHVTypeFunctor: { ShaderVariableFunctor *p = dynamic_cast<ShaderVariableFunctor *>(pVar); if(0x0000 == (p->getDependency() & uiUpdateDependents)) continue; if(*mLocIt == -1) { OSGGETGLFUNCBYID_GL3_ES( glGetUniformLocation, osgGlGetUniformLocation, ShaderProgram::getFuncIdGetUniformLocation(), pWin); *mLocIt = osgGlGetUniformLocation(uiProgram, p->getName().c_str()); } p->evaluate(pEnv, *mLocIt); } break; default: break; } } }
TEST(ShaderVariableTest, FindInfoByMappedName) { // struct A { // float x[2]; // vec3 y; // }; // struct B { // A a[3]; // }; // B uni[2]; ShaderVariable uni; uni.arraySize = 2; uni.name = "uni"; uni.mappedName = "m_uni"; uni.structName = "B"; { ShaderVariable a; a.arraySize = 3; a.name = "a"; a.mappedName = "m_a"; a.structName = "A"; { ShaderVariable x(GL_FLOAT, 2); x.name = "x"; x.mappedName = "m_x"; a.fields.push_back(x); ShaderVariable y(GL_FLOAT_VEC3, 0); y.name = "y"; y.mappedName = "m_y"; a.fields.push_back(y); } uni.fields.push_back(a); } const ShaderVariable *leafVar = NULL; std::string originalFullName; std::string mappedFullName = "wrongName"; EXPECT_FALSE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); mappedFullName = "m_uni"; EXPECT_TRUE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); EXPECT_EQ(&uni, leafVar); EXPECT_STREQ("uni", originalFullName.c_str()); mappedFullName = "m_uni[0].m_a[1].wrongName"; EXPECT_FALSE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); mappedFullName = "m_uni[0].m_a[1].m_x"; EXPECT_TRUE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); EXPECT_EQ(&(uni.fields[0].fields[0]), leafVar); EXPECT_STREQ("uni[0].a[1].x", originalFullName.c_str()); mappedFullName = "m_uni[0].m_a[1].m_x[0]"; EXPECT_TRUE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); EXPECT_EQ(&(uni.fields[0].fields[0]), leafVar); EXPECT_STREQ("uni[0].a[1].x[0]", originalFullName.c_str()); mappedFullName = "m_uni[0].m_a[1].m_y"; EXPECT_TRUE(uni.findInfoByMappedName( mappedFullName, &leafVar, &originalFullName)); EXPECT_EQ(&(uni.fields[0].fields[1]), leafVar); EXPECT_STREQ("uni[0].a[1].y", originalFullName.c_str()); }
quint32 Shader::load() { auto program = oglfunc.glCreateProgram(); auto vertex = oglfunc.glCreateShader(GL_VERTEX_SHADER); auto tessalation1 = oglfunc.glCreateShader(GL_TESS_CONTROL_SHADER); auto tessalation2 = oglfunc.glCreateShader(GL_TESS_EVALUATION_SHADER); auto geometry = oglfunc.glCreateShader(GL_GEOMETRY_SHADER); auto fragment = oglfunc.glCreateShader(GL_FRAGMENT_SHADER); auto source = m_sources[0].toStdString().c_str(); oglfunc.glShaderSource(vertex,1, &source,nullptr); oglfunc.glCompileShader(vertex); int result; oglfunc.glGetShaderiv(vertex,GL_COMPILE_STATUS, &result); if(result ==GL_FALSE){ int length; oglfunc.glGetShaderiv(vertex,GL_INFO_LOG_LENGTH,&length); QVector<char> error(length); oglfunc.glGetShaderInfoLog(vertex,length,&length,&error[0]); system::logger.writeToGELog("Failed to initialize Vertex Shader! "); system::logger.writeToGELog(&error[0]); oglfunc.glDeleteShader(vertex); return 0; } if(m_sources[1] != NULL){ source = NULL; source = m_sources[1].toStdString().c_str(); oglfunc.glShaderSource(tessalation1,1, &source,nullptr); oglfunc.glCompileShader(tessalation1); int result; oglfunc.glGetShaderiv(tessalation1,GL_COMPILE_STATUS, &result); if(result ==GL_FALSE){ int length; oglfunc.glGetShaderiv(tessalation1,GL_INFO_LOG_LENGTH,&length); QVector<char> error(length); oglfunc.glGetShaderInfoLog(tessalation1,length,&length,&error[0]); system::logger.writeToGELog("Failed to initialize Vertex Shader! "); system::logger.writeToGELog(&error[0]); oglfunc.glDeleteShader(tessalation1); return 0; } } if(m_sources[2] != NULL){ source = NULL; source = m_sources[2].toStdString().c_str(); oglfunc.glShaderSource(tessalation2,1, &source,nullptr); oglfunc.glCompileShader(tessalation2); int result; oglfunc.glGetShaderiv(tessalation2,GL_COMPILE_STATUS, &result); if(result ==GL_FALSE){ int length; oglfunc.glGetShaderiv(tessalation2,GL_INFO_LOG_LENGTH,&length); QVector<char> error(length); oglfunc.glGetShaderInfoLog(tessalation2,length,&length,&error[0]); system::logger.writeToGELog("Failed to initialize Vertex Shader! "); system::logger.writeToGELog(&error[0]); oglfunc.glDeleteShader(tessalation2); return 0; } } if(m_sources[3] != NULL){ source = NULL; source = m_sources[3].toStdString().c_str(); oglfunc.glShaderSource(geometry,1, &source,nullptr); oglfunc.glCompileShader(tessalation2); int result; oglfunc.glGetShaderiv(geometry,GL_COMPILE_STATUS, &result); if(result ==GL_FALSE){ int length; oglfunc.glGetShaderiv(geometry,GL_INFO_LOG_LENGTH,&length); QVector<char> error(length); oglfunc.glGetShaderInfoLog(geometry,length,&length,&error[0]); system::logger.writeToGELog("Failed to initialize Vertex Shader! "); system::logger.writeToGELog(&error[0]); oglfunc.glDeleteShader(geometry); return 0; } } source = NULL; source = m_sources[4].toStdString().c_str(); oglfunc.glShaderSource(fragment,1, &source,nullptr); oglfunc.glCompileShader(fragment); oglfunc.glGetShaderiv(fragment,GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { int length; oglfunc.glGetShaderiv(fragment, GL_INFO_LOG_LENGTH, &length); std::vector<char> error(length); oglfunc.glGetShaderInfoLog(fragment, length, &length, &error[0]); system::logger.writeToGELog("Failed to initialize Fragment Shader!"); system::logger.writeToGELog(&error[0]); oglfunc.glDeleteShader(fragment); return 0; } //attach all shaders to the program oglfunc.glAttachShader(program, vertex); oglfunc.glAttachShader(program, tessalation1); oglfunc.glAttachShader(program, tessalation2); oglfunc.glAttachShader(program, geometry); oglfunc.glAttachShader(program, fragment); //Link the program oglfunc.glLinkProgram(program); oglfunc.glValidateProgram(program); //set shader uniforms GLint ucount; oglfunc.glGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, &ucount); for(int i = 0; i < ucount; i++){ ShaderVariable *temp = new ShaderVariable(); GLsizei actualLength =0; GLchar *nameData = nullptr; GLint arraySize = 0; GLenum type = 0; std::string tempstr; int maxSize = tempstr.max_size(); oglfunc.glGetActiveUniform(program,i,maxSize,&actualLength, &arraySize, &type, nameData); temp->setName(nameData); temp->setSize(actualLength); temp->setLocation(oglfunc.glGetUniformLocation(program,nameData)); union{ float *afvalue; int *ivalue; double *dvalue; }; switch(type){ case GL_FLOAT: temp->setType(SUT_FLOAT); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); temp->setValue<float>(*afvalue); break; case GL_INT: temp->setType(SUT_INT); oglfunc.glGetUniformiv(program,temp->getLocation(),ivalue); temp->setValue<int>(*ivalue); break; case GL_FLOAT_VEC2: temp->setType(SUT_VEC2); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); //temp->setValue<math::vec2<float>>(math::vec2<float>(fvalue[0],fvalue[1])); temp->setValue<math::vec2<float>>(math::vec2<float>(afvalue[0],afvalue[1])); break; case GL_FLOAT_VEC3: temp->setType(SUT_VEC3); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); // temp->setValue<math::vec3<float>>(math::vec3<float>(fvalue[0],fvalue[1],fvalue[2])); temp->setValue<math::vec3<float>>(math::vec3<float>(afvalue[0],afvalue[1],afvalue[2])); break; case GL_FLOAT_VEC4: temp->setType(SUT_VEC4); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); //temp->setValue<math::vec4<float>>(math::vec4<float>(fvalue[0],fvalue[1],fvalue[2],fvalue[3])); temp->setValue<math::vec4<float>>(math::vec4<float>(afvalue[0],afvalue[1],afvalue[2],afvalue[3])); break; case GL_INT_VEC2: temp->setType(SUT_IVEC2); oglfunc.glGetUniformiv(program,temp->getLocation(),ivalue); temp->setValue<math::vec2<int>>(math::vec2<int>(ivalue[0],ivalue[1])); break; case GL_INT_VEC3: temp->setType(SUT_IVEC3); oglfunc.glGetUniformiv(program,temp->getLocation(),ivalue); temp->setValue<math::vec3<int>>(math::vec3<int>(ivalue[0],ivalue[1],ivalue[2])); break; case GL_INT_VEC4: temp->setType(SUT_IVEC4); oglfunc.glGetUniformiv(program,temp->getLocation(),ivalue); temp->setValue<math::vec4<int>>(math::vec4<int>(ivalue[0],ivalue[1],ivalue[2],ivalue[3])); break; } m_uniforms.push_back(temp); } //set shader attributes GLint acount; oglfunc.glGetProgramInterfaceiv(program,GL_PROGRAM_INPUT,GL_ACTIVE_ATTRIBUTES,&acount); for(int j = 0 ; j < acount; j++){ ShaderVariable *temp = new ShaderVariable(); GLsizei actualLength =0; GLchar *nameData = nullptr; GLint arraySize; GLenum type = 0; std::string tempstr; int maxSize = tempstr.max_size(); oglfunc.glGetActiveAttrib(program,j,maxSize,&actualLength, &arraySize, &type, nameData); temp->setName(nameData); temp->setSize(actualLength); temp->setLocation(oglfunc.glGetUniformLocation(program,nameData)); union{ float *afvalue; int *aivalue; double *dvalue; }; //TODO: FIX THIS UP! switch(type){ case GL_FLOAT: temp->setType(SUT_FLOAT); //oglfunc.glGetAttribiv(program,temp->getLocation(),afvalue); //temp->setValue<float>(*afvalue); break; case GL_INT: temp->setType(SUT_INT); oglfunc.glGetUniformiv(program,temp->getLocation(),aivalue); temp->setValue<int>(*aivalue); break; case GL_FLOAT_VEC2: temp->setType(SUT_VEC2); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); //temp->setValue<math::vec2<float>>(math::vec2<float>(fvalue[0],fvalue[1])); temp->setValue<math::vec2<float>>(math::vec2<float>(afvalue[0],afvalue[1])); break; case GL_FLOAT_VEC3: temp->setType(SUT_VEC3); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); // temp->setValue<math::vec3<float>>(math::vec3<float>(fvalue[0],fvalue[1],fvalue[2])); temp->setValue<math::vec3<float>>(math::vec3<float>(afvalue[0],afvalue[1],afvalue[2])); break; case GL_FLOAT_VEC4: temp->setType(SUT_VEC4); oglfunc.glGetUniformfv(program,temp->getLocation(),afvalue); //temp->setValue<math::vec4<float>>(math::vec4<float>(fvalue[0],fvalue[1],fvalue[2],fvalue[3])); temp->setValue<math::vec4<float>>(math::vec4<float>(afvalue[0],afvalue[1],afvalue[2],afvalue[3])); break; case GL_INT_VEC2: temp->setType(SUT_IVEC2); oglfunc.glGetUniformiv(program,temp->getLocation(),aivalue); temp->setValue<math::vec2<int>>(math::vec2<int>(aivalue[0],aivalue[1])); break; case GL_INT_VEC3: temp->setType(SUT_IVEC3); oglfunc.glGetUniformiv(program,temp->getLocation(),aivalue); temp->setValue<math::vec3<int>>(math::vec3<int>(aivalue[0],aivalue[1],aivalue[2])); break; case GL_INT_VEC4: temp->setType(SUT_IVEC4); oglfunc.glGetUniformiv(program,temp->getLocation(),aivalue); temp->setValue<math::vec4<int>>(math::vec4<int>(aivalue[0],aivalue[1],aivalue[2],aivalue[3])); break; } m_attributes.push_back(temp); } oglfunc.glDeleteShader(vertex); oglfunc.glDeleteShader(tessalation1); oglfunc.glDeleteShader(tessalation2); oglfunc.glDeleteShader(geometry); oglfunc.glDeleteShader(fragment); return program; }