QGLShaderProgram *MGLES2Renderer::compileShaderProgram(const QString &frag, const QString &vert) { const QString fragFilename = (frag.isEmpty()) ? defaultFragmentShader() : frag; QGLShader fragShader(QGLShader::Fragment, d_ptr->m_glContext); if (!fragShader.compileSourceFile(fragFilename)) { mWarning("MGLES2Renderer") << "failed to compile fragment shader" << fragFilename << '\n' << fragShader.log(); return 0; } const QString vertFilename = (vert.isEmpty()) ? defaultVertexShader() : vert; QGLShader vertShader(QGLShader::Vertex, d_ptr->m_glContext); if (!vertShader.compileSourceFile(vertFilename)) { mWarning("MGLES2Renderer") << "failed to compile vertex shader" << vertFilename << '\n' << vertShader.log(); return 0; } QGLShaderProgram *const program = new QGLShaderProgram(d_ptr->m_glContext); if (program->addShader(&fragShader) && program->addShader(&vertShader)) { // bind needed attribute arrays to specific indices -- TODO: What's this for exactly? program->bindAttributeLocation("vertex", M_ATTR_VERTEX); program->bindAttributeLocation("texCoord", M_ATTR_TCOORD); program->bindAttributeLocation("color", M_ATTR_VCOLOR); // TODO: default context implicit here, but not above? if (program->link() && program->bind()) { // Setup default texturing uniforms here so we dont need setup them in runtime const QByteArray prefix("texture"); GLint maxTexUnits = 0; glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexUnits); for (int i = 0; i < maxTexUnits; ++i) { const int loc = program->uniformLocation(prefix + QByteArray::number(i)); if (loc >= 0) program->setUniformValue(loc, GLuint(i)); } } return program; } mWarning("MGLES2Renderer") << "failed to link shader program" << (fragFilename + ':' + vertFilename); delete program; return 0; }
ShaderManager::ShaderManager() { addShaderSource("osgPango-vert", osg::Shader::VERTEX, defaultVertexShader()); addShaderSource("osgPango-frag1", osg::Shader::FRAGMENT, createBackToFrontShader(1)); addShaderSource("osgPango-frag2", osg::Shader::FRAGMENT, createBackToFrontShader(2)); addShaderSource("osgPango-distanceField", osg::Shader::FRAGMENT, createDistanceFieldShader()); }