//-------------------------------------------------------------------- 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; }
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); }