void SimpleMesh::addIndex(unsigned int idx) { if (indices_.empty()) { addIndicies(Mesh::getDefaultMeshInfo(), std::make_shared<IndexBuffer>()); } static_cast<IndexBufferRAM*>(indices_[0].second->getEditableRepresentation<BufferRAM>()) ->add(idx); }
void SimpleMesh::setIndicesInfo(DrawType dt, ConnectivityType ct) { if (indices_.empty()) { addIndicies(Mesh::MeshInfo(dt, ct), std::make_shared<IndexBuffer>()); } else { indices_[0].first = Mesh::MeshInfo(dt, ct); } }
std::shared_ptr<SimpleMesh> SimpleMeshCreator::sphere(float radius, unsigned int numLoops, unsigned int segmentsPerLoop, vec4 color) { auto spheremesh = std::make_shared<SimpleMesh>(); numLoops = std::max(4u, numLoops); segmentsPerLoop = std::max(8u, segmentsPerLoop); // Set identity matrix spheremesh->setModelMatrix(mat4(1.f)); // Create Vertices auto normals = std::make_shared<Vec3BufferRAM>((numLoops + 1) * (segmentsPerLoop + 1)); auto normalBuffer = std::make_shared<Buffer<vec3>>(normals); unsigned int pointsPerLine = segmentsPerLoop + 1; for (unsigned int i = 0; i <= numLoops; ++i) { for (unsigned int j = 0; j <= segmentsPerLoop; ++j) { float theta = (i * static_cast<float>(M_PI) / numLoops); // + ((static_cast<float>(M_PI) * j) / (segmentsPerLoop * numLoops)); if (i == numLoops) theta = static_cast<float>(M_PI); float phi = j * 2 * static_cast<float>(M_PI) / segmentsPerLoop; float sinTheta = std::sin(theta); float sinPhi = std::sin(phi); float cosTheta = std::cos(theta); float cosPhi = std::cos(phi); vec3 normal(cosPhi * sinTheta, sinPhi * sinTheta, cosTheta); vec3 vert(normal * radius); vec3 texCoord(static_cast<float>(j) / segmentsPerLoop, static_cast<float>(i) / numLoops, 0.0f); spheremesh->addVertex(vert, texCoord, color); normals->set(i * pointsPerLine + j, normal); } } spheremesh->addBuffer(BufferType::NormalAttrib, normalBuffer); // Create Indices // compute indices spheremesh->setIndicesInfo(DrawType::Triangles, ConnectivityType::None); for (unsigned int y = 0; y < numLoops; ++y) { auto indices = std::make_shared<IndexBufferRAM>(pointsPerLine * 2); auto indexBuf = std::make_shared<IndexBuffer>(indices); unsigned int offset = y * pointsPerLine; std::size_t count = 0; for (unsigned int x = 0; x < pointsPerLine; ++x) { indices->set(count++, offset + x); indices->set(count++, offset + x + pointsPerLine); } spheremesh->addIndicies(Mesh::MeshInfo(DrawType::Triangles, ConnectivityType::Strip), indexBuf); } return spheremesh; }
std::shared_ptr<SimpleMesh> SimpleMeshCreator::plane(glm::vec3 pos, glm::vec2 extent, unsigned int meshResX, unsigned int meshResY) { auto plane = std::make_shared<SimpleMesh>(); // Set identity matrix plane->setModelMatrix(mat4(1.f)); meshResX = std::max(1u, meshResX); meshResY = std::max(1u, meshResY); glm::vec3 p0(pos - glm::vec3(extent, 0.0f) * 0.5f); glm::vec3 texCoordDelta(1.0f / glm::vec2(meshResX, meshResY), 0.0f); glm::vec3 stepDelta(extent.x * texCoordDelta.x, extent.y * texCoordDelta.y, 0.0f); unsigned int pointsPerLine = meshResX + 1; const glm::vec4 color(0.6f, 0.6f, 0.6f, 1.0f); auto normals = std::make_shared<Vec3BufferRAM>((meshResX + 1) * (meshResY + 1)); auto normalBuffer = std::make_shared<Buffer<vec3>>(normals); for (unsigned int y = 0; y <= meshResY; ++y) { for (unsigned int x = 0; x <= meshResX; ++x) { glm::vec3 tCoord(texCoordDelta * glm::vec3(x, y, 0.0f)); plane->addVertex(p0 + stepDelta * glm::vec3(x, y, 0.0f), tCoord, color); normals->set(y * pointsPerLine + x, vec3(0.0f, 0.0f, 1.0f)); } } plane->addBuffer(BufferType::NormalAttrib, normalBuffer); // compute indices plane->setIndicesInfo(DrawType::Triangles, ConnectivityType::None); for (unsigned int y = 0; y < meshResY; ++y) { auto indices = std::make_shared<IndexBufferRAM>(pointsPerLine * 2); auto indexBuf = std::make_shared<IndexBuffer>(indices); unsigned int offset = y * pointsPerLine; std::size_t count = 0; for (unsigned int x = 0; x < pointsPerLine; ++x) { indices->set(count++, offset + x); indices->set(count++, offset + x + pointsPerLine); } plane->addIndicies(Mesh::MeshInfo(DrawType::Triangles, ConnectivityType::Strip), indexBuf); } return plane; }
SimpleMesh::SimpleMesh(DrawType dt, ConnectivityType ct) : Mesh(dt, ct) { addBuffer(BufferType::POSITION_ATTRIB, std::make_shared<Buffer<vec3>>()); // pos 0 addBuffer(BufferType::TEXCOORD_ATTRIB, std::make_shared<Buffer<vec3>>()); // pos 1 addBuffer(BufferType::COLOR_ATTRIB, std::make_shared<Buffer<vec4>>()); // pos 2 addIndicies(Mesh::MeshInfo(dt, ct), std::make_shared<IndexBuffer>()); }
SimpleMesh::SimpleMesh(DrawType dt, ConnectivityType ct) : Mesh(dt, ct) { addBuffer(BufferType::PositionAttrib, std::make_shared<Buffer<vec3>>()); // pos 0 addBuffer(BufferType::TexcoordAttrib, std::make_shared<Buffer<vec3>>()); // pos 1 addBuffer(BufferType::ColorAttrib, std::make_shared<Buffer<vec4>>()); // pos 2 addIndicies(Mesh::MeshInfo(dt, ct), std::make_shared<IndexBuffer>()); }