Example #1
0
void JSONValue::WriteIndent(String& dest, int indent)
{
    uint oldLength = dest.Length();
    dest.Resize(oldLength + indent);
    for (int i = 0; i < indent; ++i)
        dest[oldLength + i] = ' ';
}
Example #2
0
static int Deserializer_Read(duk_context* ctx)
{
    duk_int_t magic = duk_get_current_magic(ctx);

    duk_push_this(ctx);

    // safe cast based on type check above
    Deserializer* deserial = CastToDeserializer(ctx, duk_get_top_index(ctx));

    duk_pop(ctx);

    if (!deserial)
    {
        duk_push_boolean(ctx, 0);
        return 1;
    }

    char* data;
    String str;
    size_t length;

    IO_MAGIC_TYPE v = (IO_MAGIC_TYPE) magic;

    bool success = false;

    switch(v)
    {
        case IO_MAGIC_INT:
            duk_push_number(ctx, (double) deserial->ReadInt());
            return 1;
        case IO_MAGIC_STRING:
            length = deserial->GetSize() - deserial->GetPosition();
            str.Resize(length + 1);
            deserial->Read(&str[0], length);
            str[length] = '\0';
            duk_push_string(ctx, str.CString());
            return 1;
        case IO_MAGIC_ZEROSTRING:
            success = duk_push_string(ctx, deserial->ReadString().CString());
            return 1;
        case IO_MAGIC_BINARY:
            length = deserial->GetSize() - deserial->GetPosition();
            duk_push_fixed_buffer(ctx, length);
            duk_push_buffer_object(ctx, -1, 0, length, DUK_BUFOBJ_UINT8ARRAY);
            duk_replace(ctx, -2);
            data = (char*) duk_require_buffer_data(ctx, 0, &length);
            success = deserial->Read(data, length);
            return 1;
        default:
            break;
    }

    duk_push_undefined(ctx);

    return 1;

}
Example #3
0
String Scene::GetVarNamesAttr() const
{
    String ret;

    if (!varNames_.Empty())
    {
        for (HashMap<StringHash, String>::ConstIterator i = varNames_.Begin(); i != varNames_.End(); ++i)
            ret += i->second_ + ';';

        ret.Resize(ret.Length() - 1);
    }

    return ret;
}
Example #4
0
void BufferToString(String& dest, const void* data, unsigned size)
{
    // Precalculate needed string size
    const unsigned char* bytes = (const unsigned char*)data;
    unsigned length = 0;
    for (unsigned i = 0; i < size; ++i)
    {
        // Room for separator
        if (i)
            ++length;

        // Room for the value
        if (bytes[i] < 10)
            ++length;
        else if (bytes[i] < 100)
            length += 2;
        else
            length += 3;
    }

    dest.Resize(length);
    unsigned index = 0;

    // Convert values
    for (unsigned i = 0; i < size; ++i)
    {
        if (i)
            dest[index++] = ' ';

        if (bytes[i] < 10)
        {
            dest[index++] = '0' + bytes[i];
        }
        else if (bytes[i] < 100)
        {
            dest[index++] = (char)('0' + bytes[i] / 10);
            dest[index++] = (char)('0' + bytes[i] % 10);
        }
        else
        {
            dest[index++] = (char)('0' + bytes[i] / 100);
            dest[index++] = (char)('0' + bytes[i] % 100 / 10);
            dest[index++] = (char)('0' + bytes[i] % 10);
        }
    }
}
static String GenerateNameFromType(StringHash typeHash)
{
    if (unknownTypeToName.Contains(typeHash))
        return unknownTypeToName[typeHash];

    String test;

    // Begin brute-force search
    unsigned numLetters = letters.Length();
    unsigned combinations = numLetters;
    bool found = false;

    for (unsigned i = 1; i < 6; ++i)
    {
        test.Resize(i);

        for (unsigned j = 0; j < combinations; ++j)
        {
            unsigned current = j;

            for (unsigned k = 0; k < i; ++k)
            {
                test[k] = letters[current % numLetters];
                current /= numLetters;
            }

            if (StringHash(test) == typeHash)
            {
                found = true;
                break;
            }
        }

        if (found)
            break;

        combinations *= numLetters;
    }

    unknownTypeToName[typeHash] = test;
    return test;
}
bool ShaderProgram::Link()
{
    PROFILE(LinkShaderProgram);

    Release();

    if (!graphics || !graphics->IsInitialized())
    {
        LOGERROR("Can not link shader program without initialized Graphics subsystem");
        return false;
    }
    if (!vs || !ps)
    {
        LOGERROR("Shader(s) are null, can not link shader program");
        return false;
    }
    if (!vs->GLShader() || !ps->GLShader())
    {
        LOGERROR("Shaders have not been compiled, can not link shader program");
        return false;
    }

    const String& vsSourceCode = vs->Parent() ? vs->Parent()->SourceCode() : String::EMPTY;
    const String& psSourceCode = ps->Parent() ? ps->Parent()->SourceCode() : String::EMPTY;

    program = glCreateProgram();
    if (!program)
    {
        LOGERROR("Could not create shader program");
        return false;
    }

    glAttachShader(program, vs->GLShader());
    glAttachShader(program, ps->GLShader());
    glLinkProgram(program);

    int linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked)
    {
        int length, outLength;
        String errorString;

        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
        errorString.Resize(length);
        glGetProgramInfoLog(program, length, &outLength, &errorString[0]);
        glDeleteProgram(program);
        program = 0;

        LOGERRORF("Could not link shaders %s: %s", FullName().CString(), errorString.CString());
        return false;
    }

    LOGDEBUGF("Linked shaders %s", FullName().CString());

    glUseProgram(program);

    char nameBuffer[MAX_NAME_LENGTH];
    int numAttributes, numUniforms, numUniformBlocks, nameLength, numElements;
    GLenum type;

    attributes.Clear();

    glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttributes);
    for (int i = 0; i < numAttributes; ++i)
    {
        glGetActiveAttrib(program, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, &numElements, &type, nameBuffer);

        VertexAttribute newAttribute;
        newAttribute.name = String(nameBuffer, nameLength);
        newAttribute.semantic = SEM_POSITION;
        newAttribute.index = 0;

        for (size_t j = 0; elementSemanticNames[j]; ++j)
        {
            if (newAttribute.name.StartsWith(elementSemanticNames[j], false))
            {
                int index = NumberPostfix(newAttribute.name);
                if (index >= 0)
                    newAttribute.index = (unsigned char)index;
                break;
            }
            newAttribute.semantic = (ElementSemantic)(newAttribute.semantic + 1);
        }

        if (newAttribute.semantic == MAX_ELEMENT_SEMANTICS)
        {
            LOGWARNINGF("Found vertex attribute %s with no known semantic in shader program %s", newAttribute.name.CString(), FullName().CString());
            continue;
        }

        newAttribute.location = glGetAttribLocation(program, newAttribute.name.CString());
        attributes.Push(newAttribute);
    }

    glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numUniforms);
    int numTextures = 0;
    for (int i = 0; i < numUniforms; ++i)
    {
        glGetActiveUniform(program, i, MAX_NAME_LENGTH, &nameLength, &numElements, &type, nameBuffer);

        String name(nameBuffer, nameLength);
        if (type >= GL_SAMPLER_1D && type <= GL_SAMPLER_2D_SHADOW)
        {
            // Assign sampler uniforms to a texture unit according to the number appended to the sampler name
            int location = glGetUniformLocation(program, name.CString());
            int unit = NumberPostfix(name);
            // If no unit number specified, assign in appearance order starting from unit 0
            if (unit < 0)
                unit = numTextures;

            // Array samplers may have multiple elements, assign each sequentially
            if (numElements > 1)
            {
                Vector<int> units;
                for (int j = 0; j < numElements; ++j)
                    units.Push(unit++);
                glUniform1iv(location, numElements, &units[0]);
            }
            else
                glUniform1iv(location, 1, &unit);

            numTextures += numElements;
        }
    }

    glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks);
    for (int i = 0; i < numUniformBlocks; ++i)
    {
        glGetActiveUniformBlockName(program, i, (GLsizei)MAX_NAME_LENGTH, &nameLength, nameBuffer);

        // Determine whether uniform block belongs to vertex or pixel shader
        String name(nameBuffer, nameLength);
        bool foundVs = vsSourceCode.Contains(name);
        bool foundPs = psSourceCode.Contains(name);
        if (foundVs && foundPs)
        {
            LOGWARNINGF("Found uniform block %s in both vertex and pixel shader in shader program %s");
            continue;
        }

        // Vertex shader constant buffer bindings occupy slots starting from zero to maximum supported, pixel shader bindings
        // from that point onward
        unsigned blockIndex = glGetUniformBlockIndex(program, name.CString());

        int bindingIndex = NumberPostfix(name);
        // If no number postfix in the name, use the block index
        if (bindingIndex < 0)
            bindingIndex = blockIndex;
        if (foundPs)
            bindingIndex += (unsigned)graphics->NumVSConstantBuffers();

        glUniformBlockBinding(program, blockIndex, bindingIndex);
    }

    return true;
}