Ejemplo n.º 1
0
    //--------------------------------------------------------------------
    Status MeshManager::mLoad(std::shared_ptr<Mesh> mesh, const std::string &sid,
                              std::vector<glm::vec3> &positions,
                              std::vector<glm::vec2> &uvs,
                              std::vector<glm::vec3> &flatNormals,
                              std::vector<VertexIndices> &vertexIndices) const {

        bool hasUv, hasFlat, hasSmooth;
        hasUv = !uvs.empty();
        if (!hasUv) {
            Log::trace(TAG, "no UV mapping found for mesh \"%s\"", sid.c_str());
        }

        hasFlat = !flatNormals.empty();
        if (!hasFlat) {
            Log::trace(TAG, "no Flat normal mapping found for mesh \"%s\"", sid.c_str());
        }

        // generates normals
        std::vector<glm::vec3> smoothNormals;
        if (!hasFlat) {
            generateFlatNormals(flatNormals, positions, vertexIndices);
        }
        generateSmoothNormals(smoothNormals, flatNormals, positions, vertexIndices, hasFlat);
        hasSmooth = true; //TODO metadata

        if(!hasFlat) { //TODO handle it with metadata
            flatNormals.clear(); //no need from there
        }

        std::vector<U16> indices;
        std::vector<Vertex> vertices;
        // map one Vertex object to one or many VertexIndices
        std::map<VertexIndices, U16> indexMap;

        U16 currentVertexIndex = 0;
        //create Vertex objects out of VertexIndices.
        for (const VertexIndices& vi : vertexIndices) {

            // if Vertex object of this indices doesn't exist already
            if (indexMap.find(vi) == indexMap.end()) {
                //create it & refer to it.
                indexMap[vi] = currentVertexIndex;
                indices.push_back(currentVertexIndex);
                currentVertexIndex++;

                Vertex v;
                v.setPosition(positions[vi.p]);
                if (hasUv) {
                    v.setUv(uvs[vi.uv]);
                }
                if (hasFlat) {
                    v.setFlatNormal(flatNormals[vi.fn]);
                }
                if (hasSmooth) {
                    v.setSmoothNormal(smoothNormals[vi.sn]);
                }
                vertices.push_back(v);
            } else {
                indices.push_back(indexMap[vi]);
            }
        }

        U32 vertexSize = 0;
        U32 vertexCount = (U32) vertices.size();

        //Positions
        VertexElement positionElement(VertexElement::Semantic::POSITION, 3, GL_FLOAT, vertexSize);
        vertexSize += positionElement.getSizeInByte();
        mesh->addVertexElement(positionElement);


        //Normals
        if (hasFlat) {
            VertexElement flatNormalElement(VertexElement::Semantic::FLAT_NORMAL, 3, GL_FLOAT, vertexSize);
            vertexSize += flatNormalElement.getSizeInByte();
            mesh->addVertexElement(flatNormalElement);
        }
        if (hasSmooth) {
            VertexElement smoothNormalElement(VertexElement::Semantic::SMOOTH_NORMAL, 3, GL_FLOAT, vertexSize);
            vertexSize += smoothNormalElement.getSizeInByte();
            mesh->addVertexElement(smoothNormalElement);
        }

        // UVs
        if (hasUv) {
            VertexElement uvElement(VertexElement::Semantic::UV, 2, GL_FLOAT, vertexSize);
            vertexSize += uvElement.getSizeInByte();
            mesh->addVertexElement(uvElement);
        }

        mesh->mVertexSize = vertexSize;
        mesh->mVertexCount = vertexCount;
        //Log::debug(TAG, "vertexSize=%d vertexCount=%d", vertexSize, vertexCount);
        //Log::debug(TAG, "indices=%d", indices.size());

        BYTE* data = new BYTE[vertexSize * vertexCount];

        /////////////////////////////////////////////////////////////////////////
        // Generate vertex buffer
        //delete mesh->mVertexBuffer;
        if (mesh->mVertexBuffer != nullptr) {
            mesh->mVertexBuffer->wipe();
        }
        mesh->mVertexBuffer = std::make_shared<VertexBuffer>(vertexSize, (U32) (vertexSize * vertexCount));

        /////////////////////////////////////////////////////////////////////////
        // Fills data
        for (U32 v = 0; v < vertexCount; ++v) {
            if (mesh->hasVertexElement(VertexElement::Semantic::POSITION)) {
                VertexElement ve = mesh->getVertexElement(VertexElement::Semantic::POSITION);
                memcpy(&data[v * vertexSize + ve.getOffset()], &(vertices[v].getPosition()), ve.getSizeInByte());
            }
            if (mesh->hasVertexElement(VertexElement::Semantic::FLAT_NORMAL)) {
                VertexElement ve = mesh->getVertexElement(VertexElement::Semantic::FLAT_NORMAL);
                memcpy(&data[v * vertexSize + ve.getOffset()], &(vertices[v].getFlatNormal()), ve.getSizeInByte());
            }
            if (mesh->hasVertexElement(VertexElement::Semantic::SMOOTH_NORMAL)) {
                VertexElement ve = mesh->getVertexElement(VertexElement::Semantic::SMOOTH_NORMAL);
                memcpy(&data[v * vertexSize + ve.getOffset()], &(vertices[v].getSmoothNormal()), ve.getSizeInByte());
            }
            if (mesh->hasVertexElement(VertexElement::Semantic::UV)) {
                VertexElement ve = mesh->getVertexElement(VertexElement::Semantic::UV);
                memcpy(&data[v * vertexSize + ve.getOffset()], &(vertices[v].getUv()), ve.getSizeInByte());
            }
        }

        /////////////////////////////////////////////////////////////////////////
        // Uploads data to GPU
        mesh->mVertexBuffer->writeData(0, vertexSize * vertexCount, data);
        delete[] data;


        //delete mesh->mIndexBuffer;
        if (mesh->mIndexBuffer != nullptr) {
            mesh->mIndexBuffer->wipe();
        }
        mesh->mIndexBuffer = std::make_shared<IndexBuffer>((U32) indices.size());
        mesh->mIndexBuffer->writeData(indices.data());

        mesh->mBoundingSphere = generateBoundingSphere(positions);

        Log::trace(TAG, "Mesh %s loaded", sid.c_str());
        return STATUS_OK;
    }
Ejemplo n.º 2
0
void init()
{
	GLfloat skyboxVertices[] = {
        // Positions          
        -1.0f, 1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, 1.0f, -1.0f,
        -1.0f, 1.0f, -1.0f,

        -1.0f, -1.0f, 1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f, 1.0f, -1.0f,
        -1.0f, 1.0f, -1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, -1.0f, 1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, -1.0f, 1.0f,
        -1.0f, -1.0f, 1.0f,

        -1.0f, 1.0f, -1.0f,
        1.0f, 1.0f, -1.0f,
        1.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, 1.0f,
        -1.0f, 1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, 1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f, 1.0f,
        1.0f, -1.0f, 1.0f
    };  

	planet = tetrahedron(5);
	object = ObjLoadModel("include/obj/torus.obj");

	vec3 tangent[planet.vertexNumber];
	vec3 bitangent[planet.vertexNumber];
	*tangent = *generateTangents(planet.vertexNumber, planet.points, tangent, bitangent);
	
	vec3 vna[planet.vertexNumber];
	*vna = *generateSmoothNormals(planet.vertexNumber, vna, planet.points, planet.normals);
	
	createShader(&skyboxShader, "src/shaders/skybox.vert",
		"src/shaders/skybox.frag");
	createShader(&sunShader, "src/shaders/sun.vert",
		"src/shaders/sun.frag");
	createShader(&planetShader, "src/shaders/planet.vert",
		"src/shaders/planet.frag");
		
	createShader(&atmosphereShader, "src/shaders/atmosphere.vert",
		"src/shaders/atmosphere.frag");
    
    
    glGenFramebuffers(1, &hdrFBO);
    glGenTextures(1, &colorBuffer);
    glBindTexture(GL_TEXTURE_2D, colorBuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    glGenRenderbuffers(1, &rboDepth);
    glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);
    
    glBindFramebuffer(GL_FRAMEBUFFER, hdrFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBuffer, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepth);
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        printf("Framebuffer not complete!\n");
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

	glGenVertexArrays(1, &planetVAO);
	glBindVertexArray(planetVAO);
	glGenBuffers(1, &planetVBO);
	glBindBuffer(GL_ARRAY_BUFFER, planetVBO);
	glBufferData(GL_ARRAY_BUFFER, planet.size + planet.nsize, NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, planet.size, planet.points);
	glBufferSubData(GL_ARRAY_BUFFER, planet.size, planet.nsize, vna);
	
	glBufferSubData(GL_ARRAY_BUFFER, planet.size+planet.nsize, sizeof(tangent), tangent);
	glBufferSubData(GL_ARRAY_BUFFER, planet.size+planet.nsize+sizeof(tangent), sizeof(tangent), tangent);
	
	vPosition = glGetAttribLocation(planetShader, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0));	
    vNormal = glGetAttribLocation(planetShader, "vNormal");
    glEnableVertexAttribArray(vNormal);
    glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(planet.size));
    
    vTangent = glGetAttribLocation(planetShader, "vTangent");
    glEnableVertexAttribArray(vTangent);
    glVertexAttribPointer(vTangent, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(planet.size+planet.nsize));
    
    vBitangent = glGetAttribLocation(planetShader, "vBitangent");
    glEnableVertexAttribArray(vBitangent);
    glVertexAttribPointer(vBitangent, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(planet.size+planet.nsize+sizeof(tangent)));
    
	glBindVertexArray(0);
	
	glGenVertexArrays(1, &skyboxVAO);
	glBindVertexArray(skyboxVAO);
    glGenBuffers(1, &skyboxVBO);
    glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
    vPosition = glGetAttribLocation(skyboxShader, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glBindVertexArray(0);
    
    glGenVertexArrays(1, &objectVAO);
	glBindVertexArray(objectVAO);
	glGenBuffers(1, &objectVBO);
	glBindBuffer(GL_ARRAY_BUFFER, objectVBO);
	glBufferData(GL_ARRAY_BUFFER, object.size + object.nsize, NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, object.size, object.points);
	glBufferSubData(GL_ARRAY_BUFFER, object.size, object.nsize, object.normals);
	vPosition = glGetAttribLocation(sunShader, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0));	
    
    vNormal = glGetAttribLocation(sunShader, "vNormal");
    glEnableVertexAttribArray(vNormal);
    glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(object.size));
	glBindVertexArray(0);
	
	glGenVertexArrays(1, &atmosphereVAO);
	glBindVertexArray(atmosphereVAO);
	glGenBuffers(1, &atmosphereVBO);
	glBindBuffer(GL_ARRAY_BUFFER, atmosphereVBO);
	glBufferData(GL_ARRAY_BUFFER, planet.size + planet.nsize, NULL, GL_STATIC_DRAW);
	glBufferSubData(GL_ARRAY_BUFFER, 0, planet.size, planet.points);
	glBufferSubData(GL_ARRAY_BUFFER, planet.size, planet.nsize, planet.normals);
	vPosition = glGetAttribLocation(atmosphereShader, "vPosition");
    glEnableVertexAttribArray(vPosition);
    glVertexAttribPointer(vPosition, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(0));	
    
    vNormal = glGetAttribLocation(atmosphereShader, "vNormal");
    glEnableVertexAttribArray(vNormal);
    glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), BUFFER_OFFSET(planet.size));
	glBindVertexArray(0);
	
    glEnable(GL_DEPTH_TEST);
}