Esempio n. 1
0
// generate vertex array object
void Mesh::generateVAO(Material::ShaderType key) {
#if _GVRF_USE_GLES3_
    GLuint tmpID;

    if (vao_dirty_) {
        deleteVaos();
    }

    if (vaoID_map_.find(key) != vaoID_map_.end()) {
        // already initialized
        return;
    }

    if (vertices_.size() == 0 && normals_.size() == 0
            && tex_coords_.size() == 0) {
        std::string error = "no vertex data yet, shouldn't call here. ";
        throw error;
        return;
    }

    if (vertexLoc_ == -1 && normalLoc_ == -1 && texCoordLoc_ == -1) {
        std::string error =
                "no attrib loc setup yet, please compile shader and set attribLoc first. ";
        throw error;
        return;
    }

    GLuint vaoID_ = 0;
    GLuint triangle_vboID_, vert_vboID_, norm_vboID_, tex_vboID_;

    glGenVertexArrays(1, &vaoID_);
    glBindVertexArray(vaoID_);

    glGenBuffers(1, &triangle_vboID_);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
            sizeof(unsigned short) * triangles_.size(), &triangles_[0],
            GL_STATIC_DRAW);
    numTriangles_ = triangles_.size() / 3;

    if (vertices_.size()) {
        glGenBuffers(1, &vert_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, vert_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices_.size(),
                &vertices_[0], GL_STATIC_DRAW);
        glEnableVertexAttribArray(getVertexLoc());
        glVertexAttribPointer(getVertexLoc(), 3, GL_FLOAT, 0, 0, 0);
    }

    if (normals_.size()) {
        glGenBuffers(1, &norm_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, norm_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals_.size(),
                &normals_[0], GL_STATIC_DRAW);
        glEnableVertexAttribArray(getNormalLoc());
        glVertexAttribPointer(getNormalLoc(), 3, GL_FLOAT, 0, 0, 0);
    }

    if (tex_coords_.size()) {
        glGenBuffers(1, &tex_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, tex_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * tex_coords_.size(),
                &tex_coords_[0], GL_STATIC_DRAW);
        glEnableVertexAttribArray(getTexCoordLoc());
        glVertexAttribPointer(getTexCoordLoc(), 2, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_float_keys_.begin();
            it != attribute_float_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(GLfloat) * getFloatVector(it->second).size(),
                getFloatVector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 1, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec2_keys_.begin();
            it != attribute_vec2_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec2) * getVec2Vector(it->second).size(),
                getVec2Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 2, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec3_keys_.begin();
            it != attribute_vec3_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec3) * getVec3Vector(it->second).size(),
                getVec3Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 3, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec4_keys_.begin();
            it != attribute_vec4_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec4) * getVec4Vector(it->second).size(),
                getVec4Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 4, GL_FLOAT, 0, 0, 0);
    }

    vaoID_map_[key] = vaoID_;
    triangle_vboID_map_[key] = triangle_vboID_;
    vert_vboID_map_[key] = vert_vboID_;
    norm_vboID_map_[key] = norm_vboID_;
    tex_vboID_map_[key] = tex_vboID_;

    // done generation
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    vao_dirty_ = false;
#endif
}
Esempio n. 2
0
// generate vertex array object
void Mesh::generateVAO() {
#if _GVRF_USE_GLES3_


    GLuint tmpID;

    if (!vao_dirty_) {
         return;
    }

    deleteVaos();

    if (vertices_.size() == 0 && normals_.size() == 0
            && tex_coords_.size() == 0) {
        std::string error = "no vertex data yet, shouldn't call here. ";
        throw error;
        return;
    }

    glGenVertexArrays(1, &vaoID_);
    glBindVertexArray(vaoID_);

    glGenBuffers(1, &triangle_vboID_);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle_vboID_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
            sizeof(unsigned short) * indices_.size(), &indices_[0],
            GL_STATIC_DRAW);
    numTriangles_ = indices_.size() / 3;

    if (vertices_.size()) {
        glGenBuffers(1, &vert_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, vert_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices_.size(),
                &vertices_[0], GL_STATIC_DRAW);
        GLuint vertexLoc = GLProgram::POSITION_ATTRIBUTE_LOCATION;
        glEnableVertexAttribArray(vertexLoc);
        glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, 0, 0, 0);
    }

    if (normals_.size()) {
        glGenBuffers(1, &norm_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, norm_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals_.size(),
                &normals_[0], GL_STATIC_DRAW);
        GLuint normalLoc = GLProgram::NORMAL_ATTRIBUTE_LOCATION;
        glEnableVertexAttribArray(normalLoc);
        glVertexAttribPointer(normalLoc, 3, GL_FLOAT, 0, 0, 0);
    }

    if (tex_coords_.size()) {
        glGenBuffers(1, &tex_vboID_);
        glBindBuffer(GL_ARRAY_BUFFER, tex_vboID_);
        glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * tex_coords_.size(),
                &tex_coords_[0], GL_STATIC_DRAW);
        GLuint texCoordLoc = GLProgram::TEXCOORD_ATTRIBUT_LOCATION;
        glEnableVertexAttribArray(texCoordLoc);
        glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_float_keys_.begin();
            it != attribute_float_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(GLfloat) * getFloatVector(it->second).size(),
                getFloatVector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 1, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec2_keys_.begin();
            it != attribute_vec2_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec2) * getVec2Vector(it->second).size(),
                getVec2Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 2, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec3_keys_.begin();
            it != attribute_vec3_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec3) * getVec3Vector(it->second).size(),
                getVec3Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 3, GL_FLOAT, 0, 0, 0);
    }

    for (auto it = attribute_vec4_keys_.begin();
            it != attribute_vec4_keys_.end(); ++it) {
        glGenBuffers(1, &tmpID);
        glBindBuffer(GL_ARRAY_BUFFER, tmpID);
        glBufferData(GL_ARRAY_BUFFER,
                sizeof(glm::vec4) * getVec4Vector(it->second).size(),
                getVec4Vector(it->second).data(), GL_STATIC_DRAW);
        glEnableVertexAttribArray(it->first);
        glVertexAttribPointer(it->first, 4, GL_FLOAT, 0, 0, 0);
    }

    // done generation
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    vao_dirty_ = false;
#endif
}
Esempio n. 3
0
void Mesh::createAttributeMapping(int programId,
        int& totalStride, int& attrLen)
{
    totalStride = attrLen = 0;
    if (programId == -1)
    {
        // If program id has not been set, return.
        return;
    }
    GLint numActiveAtributes;
    glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &numActiveAtributes);
    GLchar attrName[512];
    GLAttributeMapping attrData;

    for (int i = 0; i < numActiveAtributes; i++)
    {
        GLsizei length;
        GLint size;
        GLenum type;
        glGetActiveAttrib(programId, i, 512, &length, &size, &type, attrName);
        if (std::find(dynamicAttribute_Names_.begin(), dynamicAttribute_Names_.end(), attrName) != dynamicAttribute_Names_.end())
        {
            // Skip dynamic attributes. Currently only bones are dynamic attributes which changes each frame.
            // They are handled seperately.
        }
        else
        {
            attrData.type = GL_FLOAT;
            int loc = glGetAttribLocation(programId, attrName);
            attrData.index = loc;
            attrData.data = NULL;
            attrData.offset = totalStride;
            bool addData = true;
            int len = 0;

            // Two things to note --
            // 1. The 3 builtin buffers are still seperate from the maps used for the other attributes
            // 2. The attribute index *has* to be 0, 1 and 2 for position, tex_coords and normal. The
            // index from querying via glGetActiveAttrib cannot be used. Needs analysis.
            if (strcmp(attrName, "a_position") == 0)
            {
                attrData.size = 3;
                len = vertices_.size();
                attrData.data = vertices_.data();
                //attrData.index = 0;
            }
            else if (strcmp(attrName, "a_normal") == 0)
            {
                attrData.size = 3;
                len = normals_.size();
                attrData.data = normals_.data();
                //attrData.index = 1;
            }
            else if (strcmp(attrName, "a_texcoord") == 0)
            {
                attrData.size = 2;
                len = tex_coords_.size();
                attrData.data = tex_coords_.data();
                //attrData.index = 2;
            }
            else if (strcmp(attrName, "a_tex_coord") == 0)
            {
                attrData.size = 2;
                len = tex_coords_.size();
                attrData.data = tex_coords_.data();
                //attrData.index = 2;
            }
            else
            {
                switch (type)
                {
                    case GL_FLOAT:
                        attrData.size = 1;
                        {
                            const std::vector<float>& curr = getFloatVector(attrName);
                            len = curr.size();
                            attrData.data = curr.data();
                        }
                        break;
                    case GL_FLOAT_VEC2:
                        attrData.size = 2;
                        {
                            const std::vector<glm::vec2>& curr = getVec2Vector(attrName);
                            len = curr.size();
                            attrData.data = curr.data();
                        }
                        break;
                    case GL_FLOAT_VEC3:
                        attrData.size = 3;
                        {
                            const std::vector<glm::vec3>& curr = getVec3Vector(attrName);
                            len = curr.size();
                            attrData.data = curr.data();
                        }
                        break;
                    case GL_FLOAT_VEC4:
                        attrData.size = 4;
                        {
                            const std::vector<glm::vec4>& curr = getVec4Vector(attrName);
                            len = curr.size();
                            attrData.data = curr.data();
                        }
                        break;
                    default:
                        addData = false;
                        LOGE("Looking up %s failed ", attrName);
                            break;
                }
            }
            if (addData)
            {
                totalStride += attrData.size;
                attrMapping.push_back(attrData);
                if (attrLen == 0)
                    attrLen = len;
                else
                {
                    if (len != attrLen)
                        LOGE(" $$$$*** Attib length does not match %d vs %d", len, attrLen);
                }
            }
        }
    }
}