int lua_VertexAttributeBinding_addRef(lua_State* state)
{
    // Get the number of parameters.
    int paramCount = lua_gettop(state);

    // Attempt to match the parameters to a valid binding.
    switch (paramCount)
    {
        case 1:
        {
            if ((lua_type(state, 1) == LUA_TUSERDATA))
            {
                VertexAttributeBinding* instance = getInstance(state);
                instance->addRef();
                
                return 0;
            }

            lua_pushstring(state, "lua_VertexAttributeBinding_addRef - Failed to match the given parameters to a valid function signature.");
            lua_error(state);
            break;
        }
        default:
        {
            lua_pushstring(state, "Invalid number of parameters (expected 1).");
            lua_error(state);
            break;
        }
    }
    return 0;
}
예제 #2
0
VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, Effect* effect)
{
    GP_ASSERT(mesh);

    // Search for an existing vertex attribute binding that can be used.
    VertexAttributeBinding* b;
    for (size_t i = 0, count = __vertexAttributeBindingCache.size(); i < count; ++i)
    {
        b = __vertexAttributeBindingCache[i];
        GP_ASSERT(b);
        if (b->_mesh == mesh && b->_effect == effect)
        {
            // Found a match!
            b->addRef();
            return b;
        }
    }

    b = create(mesh, mesh->getVertexFormat(), 0, effect);

    // Add the new vertex attribute binding to the cache.
    if (b)
    {
        __vertexAttributeBindingCache.push_back(b);
    }

    return b;
}
int lua_VertexAttributeBinding_getRefCount(lua_State* state)
{
    // Get the number of parameters.
    int paramCount = lua_gettop(state);

    // Attempt to match the parameters to a valid binding.
    switch (paramCount)
    {
        case 1:
        {
            if ((lua_type(state, 1) == LUA_TUSERDATA))
            {
                VertexAttributeBinding* instance = getInstance(state);
                unsigned int result = instance->getRefCount();

                // Push the return value onto the stack.
                lua_pushunsigned(state, result);

                return 1;
            }
            else
            {
                lua_pushstring(state, "lua_VertexAttributeBinding_getRefCount - Failed to match the given parameters to a valid function signature.");
                lua_error(state);
            }
            break;
        }
        default:
        {
            lua_pushstring(state, "Invalid number of parameters (expected 1).");
            lua_error(state);
            break;
        }
    }
    return 0;
}
예제 #4
0
VertexAttributeBinding* VertexAttributeBinding::create(Mesh* mesh, const VertexFormat& vertexFormat, void* vertexPointer, Effect* effect)
{
    GP_ASSERT(effect);

    // One-time initialization.
    if (__maxVertexAttribs == 0)
    {
        GLint temp;
        GL_ASSERT( glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &temp) );

        __maxVertexAttribs = temp;
        if (__maxVertexAttribs <= 0)
        {
            GP_ERROR("The maximum number of vertex attributes supported by OpenGL on the current device is 0 or less.");
            return NULL;
        }
    }

    // Create a new VertexAttributeBinding.
    VertexAttributeBinding* b = new VertexAttributeBinding();

#ifdef GP_USE_VAO
    if (mesh && glGenVertexArrays)
    {
        GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, 0) );
        GL_ASSERT( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) );

        // Use hardware VAOs.
        GL_ASSERT( glGenVertexArrays(1, &b->_handle) );

        if (b->_handle == 0)
        {
            GP_ERROR("Failed to create VAO handle.");
            SAFE_DELETE(b);
            return NULL;
        }

        // Bind the new VAO.
        GL_ASSERT( glBindVertexArray(b->_handle) );

        // Bind the Mesh VBO so our glVertexAttribPointer calls use it.
        GL_ASSERT( glBindBuffer(GL_ARRAY_BUFFER, mesh->getVertexBuffer()) );
    }
    else
#endif
    {
        // Construct a software representation of a VAO.
        VertexAttribute* attribs = new VertexAttribute[__maxVertexAttribs];
        for (unsigned int i = 0; i < __maxVertexAttribs; ++i)
        {
            // Set GL defaults
            attribs[i].enabled = GL_FALSE;
            attribs[i].size = 4;
            attribs[i].stride = 0;
            attribs[i].type = GL_FLOAT;
            attribs[i].normalized = GL_FALSE;
            attribs[i].pointer = 0;
        }
        b->_attributes = attribs;
    }

    if (mesh)
    {
        b->_mesh = mesh;
        mesh->addRef();
    }
    
    b->_effect = effect;
    effect->addRef();

    // Call setVertexAttribPointer for each vertex element.
    std::string name;
    size_t offset = 0;
    for (size_t i = 0, count = vertexFormat.getElementCount(); i < count; ++i)
    {
        const VertexFormat::Element& e = vertexFormat.getElement(i);
        gameplay::VertexAttribute attrib;

        // Constructor vertex attribute name expected in shader.
        switch (e.usage)
        {
        case VertexFormat::POSITION:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_POSITION_NAME);
            break;
        case VertexFormat::NORMAL:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_NORMAL_NAME);
            break;
        case VertexFormat::COLOR:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_COLOR_NAME);
            break;
        case VertexFormat::TANGENT:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_TANGENT_NAME);
            break;
        case VertexFormat::BINORMAL:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_BINORMAL_NAME);
            break;
        case VertexFormat::BLENDWEIGHTS:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_BLENDWEIGHTS_NAME);
            break;
        case VertexFormat::BLENDINDICES:
            attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_BLENDINDICES_NAME);
            break;
        case VertexFormat::TEXCOORD0:
            if ((attrib = effect->getVertexAttribute(VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME)) != -1)
                break;

        case VertexFormat::TEXCOORD1:
        case VertexFormat::TEXCOORD2:
        case VertexFormat::TEXCOORD3:
        case VertexFormat::TEXCOORD4:
        case VertexFormat::TEXCOORD5:
        case VertexFormat::TEXCOORD6:
        case VertexFormat::TEXCOORD7:
            name = VERTEX_ATTRIBUTE_TEXCOORD_PREFIX_NAME;
            name += '0' + (e.usage - VertexFormat::TEXCOORD0);
            attrib = effect->getVertexAttribute(name.c_str());
            break;
        default:
            // This happens whenever vertex data contains extra information (not an error).
            attrib = -1;
            break;
        }

        if (attrib == -1)
        {
            //GP_WARN("Warning: Vertex element with usage '%s' in mesh '%s' does not correspond to an attribute in effect '%s'.", VertexFormat::toString(e.usage), mesh->getUrl(), effect->getId());
        }
        else
        {
            void* pointer = vertexPointer ? (void*)(((unsigned char*)vertexPointer) + offset) : (void*)offset;
            b->setVertexAttribPointer(attrib, (GLint)e.size, GL_FLOAT, GL_FALSE, (GLsizei)vertexFormat.getVertexSize(), pointer);
        }

        offset += e.size * sizeof(float);
    }

    if (b->_handle)
    {
        GL_ASSERT( glBindVertexArray(0) );
    }

    return b;
}