UInt32 ShaderExecutableChunk::handleGL(DrawEnv *pEnv, UInt32 id, Window::GLObjectStatusE mode, UInt32 uiOptions) { UInt32 returnValue = 0; Window *pWin = pEnv->getWindow(); if(!pWin->hasExtension(_extSHL)) { FWARNING(("OpenGL Shading Language is not supported, couldn't find " "extension 'GL_ARB_shading_language_100'!\n")); pWin->setGLObjectId(getGLId(), 0); return returnValue; } if(mode == Window::initialize || mode == Window::reinitialize || mode == Window::needrefresh ) { GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));; if(mode != Window::needrefresh) { if(uiProgram != 0) { OSGGETGLFUNC(OSGglDeleteProgramProc, osgGlDeleteProgram, ShaderProgram::getFuncIdDeleteProgram()); osgGlDeleteProgram(uiProgram); } OSGGETGLFUNC(OSGglCreateProgramProc, osgGlCreateProgram, ShaderProgram::getFuncIdCreateProgram()); OSGGETGLFUNC(OSGglAttachShaderProc, osgGlAttachShader, ShaderProgram::getFuncIdAttachShader()); OSGGETGLFUNC(OSGglLinkProgramProc, osgGlLinkProgram, ShaderProgram::getFuncIdLinkProgram()); uiProgram = osgGlCreateProgram(); FragmentShaderIt fIt = _mfFragmentShader.begin(); FragmentShaderIt fEnd = _mfFragmentShader.end (); for(; fIt != fEnd; ++fIt) { (*fIt)->validate(pEnv); GLuint uiShader = GLuint(pWin->getGLObjectId((*fIt)->getGLId())); if(uiShader != 0) osgGlAttachShader(uiProgram, uiShader); } GeometryShaderIt gIt = _mfGeometryShader.begin(); GeometryShaderIt gEnd = _mfGeometryShader.end (); for(; gIt != gEnd; ++gIt) { (*gIt)->validate(pEnv); GLuint uiShader = GLuint(pWin->getGLObjectId((*gIt)->getGLId())); if(uiShader != 0) osgGlAttachShader(uiProgram, uiShader); } VertexShaderIt vIt = _mfVertexShader.begin(); VertexShaderIt vEnd = _mfVertexShader.end (); for(; vIt != vEnd; ++vIt) { (*vIt)->validate(pEnv); GLuint uiShader = GLuint(pWin->getGLObjectId((*vIt)->getGLId())); if(uiShader != 0) osgGlAttachShader(uiProgram, uiShader); } // attribute binding must be done before linking updateAttribBindings(pEnv, uiProgram); // parameters must be set before linking updateParameters(pEnv, uiProgram); osgGlLinkProgram(uiProgram); GLint iInfoLength; Char8 *szInfoBuffer = NULL; OSGGETGLFUNC(OSGglGetProgramivProc, osgGlGetProgramiv, ShaderProgram::getFuncIdGetProgramiv()); osgGlGetProgramiv(uiProgram, GL_OBJECT_INFO_LOG_LENGTH_ARB, &iInfoLength); if(iInfoLength > 0) { szInfoBuffer = new Char8[iInfoLength]; szInfoBuffer[0] = '\0'; OSGGETGLFUNC(OSGglGetProgramInfoLogProc, osgGlGetProgramInfoLog, ShaderProgram::getFuncIdGetProgramInfoLog()); osgGlGetProgramInfoLog( uiProgram, iInfoLength, &iInfoLength, szInfoBuffer); } GLint iStatus = 0; osgGlGetProgramiv(uiProgram, GL_LINK_STATUS, &iStatus); if(iStatus == 0) { if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0') { FFATAL(("Couldn't link vertex and fragment program!\n%s\n", szInfoBuffer)); } else { FFATAL(("Couldn't link vertex and fragment program!\n" "No further info available\n")); } OSGGETGLFUNC(OSGglDeleteProgramProc, osgGlDeleteProgram, ShaderProgram::getFuncIdDeleteProgram()); osgGlDeleteProgram(uiProgram); uiProgram = 0; } else { if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0') { FWARNING(("SHLChunk: link status: %s\n", szInfoBuffer)); } } pWin->setGLObjectId(getGLId(), uiProgram); updateVariableLocations(pEnv, uiProgram); delete [] szInfoBuffer; } if(uiProgram != 0) { OSGGETGLFUNC(OSGglUseProgramProc, osgGlUseProgram, ShaderProgram::getFuncIdUseProgram()); pEnv->setActiveShader(uiProgram); osgGlUseProgram (uiProgram); updateVariables(pEnv, uiProgram); if(0x0000 == (uiOptions & KeepProgActive)) { pEnv->setActiveShader(0); osgGlUseProgram (0); } else { returnValue |= ProgActive; } } } return returnValue; }
UInt32 ComputeShaderChunk::handleGL(DrawEnv *pEnv, UInt32 id, Window::GLObjectStatusE mode, UInt64 uiOptions) { UInt32 returnValue = 0; Window *pWin = pEnv->getWindow(); if(!pWin->hasExtOrVersion(_arbComputeShader, 0x0403, 0xFFFF)) { FWARNING(("OpenGL compute shader is not supported, couldn't find " "extension 'GL_ARB_compute_shader'!\n")); pWin->setGLObjectId(getGLId(), 0); return returnValue; } if(mode == Window::initialize || mode == Window::reinitialize || mode == Window::needrefresh ) { GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));; if(mode != Window::needrefresh) { if(uiProgram != 0) { OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram, osgGlDeleteProgram, ShaderProgram::getFuncIdDeleteProgram(), pWin); osgGlDeleteProgram(uiProgram); } OSGGETGLFUNCBYID_GL3_ES(glCreateProgram, osgGlCreateProgram, ShaderProgram::getFuncIdCreateProgram(), pWin); OSGGETGLFUNCBYID_GL3_ES(glAttachShader, osgGlAttachShader, ShaderProgram::getFuncIdAttachShader(), pWin); OSGGETGLFUNCBYID_GL3_ES(glLinkProgram, osgGlLinkProgram, ShaderProgram::getFuncIdLinkProgram(), pWin); uiProgram = osgGlCreateProgram(); ComputeShaderIt vIt = _mfComputeShader.begin(); ComputeShaderIt vEnd = _mfComputeShader.end (); for(; vIt != vEnd; ++vIt) { (*vIt)->validate(pEnv); GLuint uiShader = GLuint(pWin->getGLObjectId((*vIt)->getGLId())); if(uiShader != 0) osgGlAttachShader(uiProgram, uiShader); } osgGlLinkProgram(uiProgram); GLint iInfoLength; Char8 *szInfoBuffer = NULL; OSGGETGLFUNCBYID_GL3_ES(glGetProgramiv, osgGlGetProgramiv, ShaderProgram::getFuncIdGetProgramiv(), pWin); osgGlGetProgramiv(uiProgram, GL_OBJECT_INFO_LOG_LENGTH_ARB, &iInfoLength); if(iInfoLength > 0) { szInfoBuffer = new Char8[iInfoLength]; szInfoBuffer[0] = '\0'; OSGGETGLFUNCBYID_GL3_ES( glGetProgramInfoLog, osgGlGetProgramInfoLog, ShaderProgram::getFuncIdGetProgramInfoLog(), pWin); osgGlGetProgramInfoLog( uiProgram, iInfoLength, &iInfoLength, szInfoBuffer); } GLint iStatus = 0; osgGlGetProgramiv(uiProgram, GL_LINK_STATUS, &iStatus); if(iStatus == 0) { if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0') { FFATAL(("Couldn't link compute program!\n%s\n", szInfoBuffer)); } else { FFATAL(("Couldn't link compute program!\n" "No further info available\n")); } OSGGETGLFUNCBYID_GL3_ES(glDeleteProgram, osgGlDeleteProgram, ShaderProgram::getFuncIdDeleteProgram(), pWin); osgGlDeleteProgram(uiProgram); uiProgram = 0; } else { if(szInfoBuffer != NULL && szInfoBuffer[0] != '\0') { FWARNING(("ComputeShaderChunk: link status: %s\n", szInfoBuffer)); } } pWin->setGLObjectId(getGLId(), uiProgram); updateVariableLocations(pEnv, uiProgram); } if(uiProgram != 0) { OSGGETGLFUNCBYID_GL3_ES(glUseProgram, osgGlUseProgram, ShaderProgram::getFuncIdUseProgram(), pWin); osgGlUseProgram(uiProgram); updateVariables(pEnv, uiProgram); if(0x0000 == (uiOptions & KeepProgActive)) { osgGlUseProgram(0); } else { returnValue |= ProgActive; } } } return returnValue; }