Exemple #1
0
/**
 * Finds the shader locations of all uniforms and textures from a given material.
 * The input material descriptor has all the possible textures and uniforms
 * that can be used by this shader. (Any material used with this shader
 * will have the same descriptor.)
 *
 * This function uses the descriptor of the input material to find and save
 * the GL shader locations of each texture and uniform. The locations are
 * saved into vectors - mTextureLocs and mUniformLocs. Each vector has an
 * entry for all of the uniforms/textures in the input material
 * (not just the ones used by this shader). If the shader does not
 * reference a particular uniform or texture, that location will be -1.
 * This function must be called after the GL shader program has
 * been selected as the current program.
 * @param material  can be any Material which uses this shader
 * @see #getUniformLoc
 */
void GLShader::findUniforms(const DataDescriptor& desc, int bindingPoint)
{
    std::vector<int>& uniformLocs = mShaderLocs[bindingPoint];

    if (uniformLocs.size() > 0)
    {
        return;
    }
    uniformLocs.resize(desc.getNumEntries(), -1);
    desc.forEachEntry([&](const DataDescriptor::DataEntry& entry) mutable
    {
        if (entry.NotUsed)
        {
            return;
        }
        int loc = glGetUniformLocation(getProgramId(), entry.Name);
        if (loc >= 0)
        {
            uniformLocs[entry.Index] = loc;
#ifdef DEBUG_SHADER
            LOGV("SHADER: program %d uniform %s loc %d", getProgramId(), entry.Name, loc);
#endif
        }
        else
        {
#ifdef DEBUG_SHADER
            LOGV("SHADER: uniform %s has no location in shader %d", entry.Name, getProgramId());
#endif
        }
    });
    checkGLError("GLShader::findUniforms");
}
Exemple #2
0
std::string GLShader::makeLayout(const DataDescriptor& desc, const char* blockName, bool useGPUBuffer)
{
    std::ostringstream stream;
    if (useGPUBuffer)
    {
        stream << "\nlayout (std140) uniform " << blockName << std::endl << "{" << std::endl;
        desc.forEachEntry([&stream](const DataDescriptor::DataEntry& entry) mutable
        {
            int nelems = entry.Count;
            stream << "   " << entry.Type << " " << entry.Name;
            if (nelems > 1)
            {
                stream << "[" << nelems << "]";
            }
            stream << ";" << std::endl;
        });
        stream << "};" << std::endl;
    }
    else
    {
        desc.forEachEntry([&stream](const DataDescriptor::DataEntry& entry) mutable
        {
            if (entry.IsSet)
            {
                int nelems = entry.Count;
                stream << "uniform " << entry.Type << " " << entry.Name;
                if (nelems > 1)
                {
                    stream << "[" << nelems << "]";
                }
                stream << ";" << std::endl;
            }
        });
    }
    return stream.str();
}