#ifndef SPHERE_H #define SPHERE_H #include #include #include struct SphereVertex { glm::vec3 position; glm::vec3 normal; // Fixed: Must be vec3 for 3D directions glm::vec2 texCoord; // Fixed: Must be vec2 for U,V coordinates }; // Generates vertex and index data for a sphere inline void generateSphere(float radius, int sectors, int stacks, std::vector &vertices, std::vector &indices) { vertices.clear(); indices.clear(); float x, y, z, xy; float nx, ny, nz, lengthInv = 1.0f / radius; float s, t; float sectorStep = 2 * M_PI / sectors; float stackStep = M_PI / stacks; float sectorAngle, stackAngle; for (int i = 0; i <= stacks; ++i) { stackAngle = M_PI / 2 - i * stackStep; xy = radius * std::cos(stackAngle); z = radius * std::sin(stackAngle); for (int j = 0; j <= sectors; ++j) { sectorAngle = j * sectorStep; // Position x = xy * std::cos(sectorAngle); y = xy * std::sin(sectorAngle); SphereVertex vertex; vertex.position = glm::vec3(x, y, z); // Normal is just the normalized position for a sphere at origin vertex.normal = glm::vec3(x * lengthInv, y * lengthInv, z * lengthInv); vertex.texCoord = glm::vec2((float)j / sectors, (float)i / stacks); vertices.push_back(vertex); } } // Index generation: connecting the stacks and sectors for (int i = 0; i < stacks; ++i) { int k1 = i * (sectors + 1); int k2 = k1 + sectors + 1; for (int j = 0; j < sectors; ++j, ++k1, ++k2) { if (i != 0) { indices.push_back(k1); indices.push_back(k2); indices.push_back(k1 + 1); } if (i != (stacks - 1)) { indices.push_back(k1 + 1); indices.push_back(k2); indices.push_back(k2 + 1); } } } } #endif