예제 #1
0
void OsmAnd::GPUAPI_OpenGLES2::preprocessFragmentShader(QString& code)
{
    const auto& fragmentShaderAdditionalPrologue = QString::fromLatin1(
        // Make some extensions required
        "#ifdef GL_EXT_shader_texture_lod                                                                                   ""\n"
        "#extension GL_EXT_shader_texture_lod : require                                                                     ""\n"
        "#endif // GL_EXT_shader_texture_lod                                                                                ""\n"
        "                                                                                                                   ""\n"
        // Fragment shader output declaration
        "#define FRAGMENT_COLOR_OUTPUT gl_FragColor                                                                         ""\n"
        "                                                                                                                   ""\n"
        // It have been reported that GL_FRAGMENT_PRECISION_HIGH may not be defined in some cases
        "#ifndef GL_FRAGMENT_PRECISION_HIGH                                                                                 ""\n"
        "#if %HighPrecisionSupported%                                                                                       ""\n"
        "#define GL_FRAGMENT_PRECISION_HIGH 1                                                                               ""\n"
        "#endif                                                                                                             ""\n"
        "#endif                                                                                                             ""\n"
        "                                                                                                                   ""\n"
        // Set default precisions (this should be the default, but never trust mobile drivers)
        "#ifdef GL_FRAGMENT_PRECISION_HIGH                                                                                  ""\n"
        "precision highp float;                                                                                             ""\n"
        "precision highp int;                                                                                               ""\n"
        "#else                                                                                                              ""\n"
        "precision highp float;                                                                                             ""\n"
        "precision highp int;                                                                                               ""\n"
        "#endif                                                                                                             ""\n"
        "                                                                                                                   ""\n");

    auto fragmentShaderAdditionalProloguePreprocessed = fragmentShaderAdditionalPrologue;
    fragmentShaderAdditionalProloguePreprocessed.replace("%HighPrecisionSupported%", QString::number(
        supportedFragmentShaderPrecisionFormats.contains(GL_HIGH_FLOAT) && supportedFragmentShaderPrecisionFormats.contains(GL_HIGH_INT) ? 1 : 0));

    code.prepend(fragmentShaderAdditionalProloguePreprocessed);
    preprocessShader(code);
}
예제 #2
0
void OsmAnd::GPUAPI_OpenGLES2::preprocessVertexShader(QString& code)
{
    const auto& vertexShaderAdditionalPrologue = QString::fromLatin1(
        // Set default precisions (this should be the default, but never trust mobile drivers)
        "precision highp float;                                                                                             ""\n"
        "precision highp int;                                                                                               ""\n"
        "                                                                                                                   ""\n");

    code.prepend(vertexShaderAdditionalPrologue);
    preprocessShader(code);
}
예제 #3
0
QOpenGLShaderProgram* ShaderMgr::findOrLoadShader(uint flags)
{
	auto it = m_shaderCache.find(flags);

	// This may also return Q_NULLPTR if the load failed.
	//We wait until user explictly forces shader reload until we try again to avoid spamming errors.
	if(it!=m_shaderCache.end())
		return *it;

	//get shader file names
	QString vShaderFile = getVShaderName(flags);
	QString gShaderFile = getGShaderName(flags);
	QString fShaderFile = getFShaderName(flags);
	qCDebug(shaderMgr)<<"Loading Scenery3d shader: flags:"<<flags<<", vs:"<<vShaderFile<<", gs:"<<gShaderFile<<", fs:"<<fShaderFile<<"";

	//load shader files & preprocess
	QByteArray vShader,gShader,fShader;

	QOpenGLShaderProgram *prog = Q_NULLPTR;

	if(preprocessShader(vShaderFile,flags,vShader) &&
			preprocessShader(gShaderFile,flags,gShader) &&
			preprocessShader(fShaderFile,flags,fShader)
			)
	{
		//check if this content-hash was already created for optimization
		//(so that shaders with different flags, but identical implementation use the same program)
		QCryptographicHash hash(QCryptographicHash::Sha256);
		hash.addData(vShader);
		hash.addData(gShader);
		hash.addData(fShader);

		QByteArray contentHash = hash.result();
		if(m_shaderContentCache.contains(contentHash))
		{
#ifndef NDEBUG
			//qCDebug(shaderMgr)<<"Using existing shader with content-hash"<<contentHash.toHex();
#endif
			prog = m_shaderContentCache[contentHash];
		}
		else
		{
			//we have to compile the shader
			prog = new QOpenGLShaderProgram();

			if(!loadShader(*prog,vShader,gShader,fShader))
			{
				delete prog;
				prog = Q_NULLPTR;
				qCCritical(shaderMgr)<<"ERROR: Shader '"<<flags<<"' could not be compiled. Fix errors and reload shaders or restart program.";
			}
#ifndef NDEBUG
			else
			{
				//qCDebug(shaderMgr)<<"Shader '"<<flags<<"' created, content-hash"<<contentHash.toHex();
			}
#endif
			m_shaderContentCache[contentHash] = prog;
		}
	}
	else
	{
		qCCritical(shaderMgr)<<"ERROR: Shader '"<<flags<<"' could not be loaded/preprocessed.";
	}


	//may put null in cache on fail!
	m_shaderCache[flags] = prog;

	return prog;
}