Skip to content

Commit

Permalink
Add Capsule
Browse files Browse the repository at this point in the history
  • Loading branch information
xorz57 committed Jun 3, 2024
1 parent 726d6f8 commit 2d6f6a3
Show file tree
Hide file tree
Showing 6 changed files with 258 additions and 1 deletion.
1 change: 1 addition & 0 deletions Example16/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_executable(Example16 src/Main.cpp
src/Application.cpp
src/Camera.cpp
src/Shapes/Capsule.cpp
src/Shapes/Circle.cpp
src/Shapes/Cube.cpp
src/Shapes/Cylinder.cpp
Expand Down
Binary file added Example16/assets/textures/capsule.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions Example16/src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "Logging.hpp"
#include "Shader.hpp"

#include "Shapes/Capsule.hpp"
#include "Shapes/Circle.hpp"
#include "Shapes/Cube.hpp"
#include "Shapes/Cylinder.hpp"
Expand Down Expand Up @@ -99,6 +100,7 @@ void Application::Run() {
camera.SetSensitivity(0.1f);
camera.SetSpeed(4.0f);

Capsule capsule;
Sphere sphere;
Cylinder cylinder;
Plane plane;
Expand Down Expand Up @@ -210,6 +212,13 @@ void Application::Run() {
shader.SetFloat4x4("u_model", circle.GetModel());
circle.Draw();

capsule.Reset();
capsule.Translate(glm::vec3(0.0f, 0.0f, 32.0f));
capsule.Rotate(glm::radians(0.0f), glm::vec3(1.0f, 1.0f, 1.0f));
capsule.Scale(glm::vec3(16.0f, 16.0f, 16.0f));
shader.SetFloat4x4("u_model", capsule.GetModel());
capsule.Draw();

const std::vector<glm::vec3> translations = {
glm::vec3(-4.0f, +2.0f, -4.0f),// 0
glm::vec3(-4.0f, +2.0f, +0.0f),// 1
Expand Down
191 changes: 191 additions & 0 deletions Example16/src/Shapes/Capsule.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
#include "Capsule.hpp"

Capsule::Capsule() {
Build(32, 16);

mVAO = VAO::Create();
mVBO = VBO<Vertex>::Create(mVertices);
mEBO1 = EBO<GLuint>::Create(mElements1);
mEBO2 = EBO<GLuint>::Create(mElements2);
mEBO3 = EBO<GLuint>::Create(mElements3);
mTexture = Texture::Create("assets/textures/capsule.png");

mVAO->Bind();
mVBO->Bind();
VAO::SetFloat3(0, sizeof(Vertex), (void *) offsetof(Vertex, position));
VAO::SetFloat2(1, sizeof(Vertex), (void *) offsetof(Vertex, texture_coordinates));
VBO<GLuint>::Unbind();
VAO::Unbind();
}

Capsule::Capsule(std::uint32_t sectors, std::uint32_t stacks) {
Build(sectors, stacks);

mVAO = VAO::Create();
mVBO = VBO<Vertex>::Create(mVertices);
mEBO1 = EBO<GLuint>::Create(mElements1);
mEBO2 = EBO<GLuint>::Create(mElements2);
mEBO3 = EBO<GLuint>::Create(mElements3);
mTexture = Texture::Create("assets/textures/capsule.png");

mVAO->Bind();
mVBO->Bind();
VAO::SetFloat3(0, sizeof(Vertex), (void *) offsetof(Vertex, position));
VAO::SetFloat2(1, sizeof(Vertex), (void *) offsetof(Vertex, texture_coordinates));
VBO<GLuint>::Unbind();
VAO::Unbind();
}

void Capsule::Build(std::uint32_t sectors, std::uint32_t stacks) {
const float height = 0.5f;

for (std::uint32_t i = 0; i <= stacks; ++i) {
const float stack_angle = glm::half_pi<float>() * static_cast<float>(i) / static_cast<float>(stacks);

const float y = 0.5f * glm::cos(stack_angle) + height;

for (std::uint32_t j = 0; j <= sectors; ++j) {
const float sector_step = 2.0f * glm::pi<float>() / static_cast<float>(sectors);
const float sector_angle = static_cast<float>(j) * sector_step;

const float x = 0.5f * glm::sin(stack_angle) * glm::cos(sector_angle);
const float z = 0.5f * glm::sin(stack_angle) * glm::sin(sector_angle);

const float u = static_cast<float>(j) / static_cast<float>(sectors);
const float v = static_cast<float>(i) / static_cast<float>(stacks * 2);

mVertices.push_back({{x, y, z}, {u, v}});
}
}

for (std::uint32_t i = 0; i <= stacks; ++i) {
const float stack_step = glm::half_pi<float>() / static_cast<float>(stacks);
const float stack_angle = glm::half_pi<float>() + static_cast<float>(i) * stack_step;

const float y = 0.5f * glm::cos(stack_angle) - height;

for (std::uint32_t j = 0; j <= sectors; ++j) {
const float sector_step = 2.0f * glm::pi<float>() / static_cast<float>(sectors);
const float sector_angle = static_cast<float>(j) * sector_step;

const float x = 0.5f * glm::sin(stack_angle) * glm::cos(sector_angle);
const float z = 0.5f * glm::sin(stack_angle) * glm::sin(sector_angle);

const float u = static_cast<float>(j) / static_cast<float>(sectors);
const float v = static_cast<float>(i + stacks) / static_cast<float>(stacks * 2);

mVertices.push_back({{x, y, z}, {u, v}});
}
}

for (std::uint32_t j = 0; j <= sectors; ++j) {
const float sector_step = 2.0f * glm::pi<float>() / static_cast<float>(sectors);
const float sector_angle = static_cast<float>(j) * sector_step;

const float x = 0.5f * glm::cos(sector_angle);
const float z = 0.5f * glm::sin(sector_angle);

const float u = static_cast<float>(j) / static_cast<float>(sectors);

mVertices.push_back({{x, height, z}, {u, 1.0f}});
mVertices.push_back({{x, -height, z}, {u, 0.0f}});
}

for (std::uint32_t i = 0; i < stacks; ++i) {
std::uint32_t k1 = i * (sectors + 1);
std::uint32_t k2 = k1 + sectors + 1;

for (std::uint32_t j = 0; j < sectors; ++j) {
mElements1.push_back(k1);
mElements1.push_back(k2);
mElements1.push_back(k1 + 1);

mElements1.push_back(k1 + 1);
mElements1.push_back(k2);
mElements1.push_back(k2 + 1);

++k1;
++k2;
}
}

const std::uint32_t offset1 = (stacks + 1) * (sectors + 1);
for (std::uint32_t i = 0; i < stacks; ++i) {
std::uint32_t k1 = offset1 + i * (sectors + 1);
std::uint32_t k2 = k1 + sectors + 1;

for (std::uint32_t j = 0; j < sectors; ++j) {
mElements2.push_back(k1);
mElements2.push_back(k1 + 1);
mElements2.push_back(k2);

mElements2.push_back(k2);
mElements2.push_back(k1 + 1);
mElements2.push_back(k2 + 1);

++k1;
++k2;
}
}

const std::uint32_t offset2 = offset1 + (stacks + 1) * (sectors + 1);
for (std::uint32_t i = 0; i < sectors; ++i) {
const std::uint32_t top1 = offset2 + i * 2;
const std::uint32_t top2 = top1 + 1;
const std::uint32_t bottom1 = top1 + 2;
const std::uint32_t bottom2 = bottom1 + 1;

mElements3.push_back(top1);
mElements3.push_back(bottom1);
mElements3.push_back(top2);

mElements3.push_back(top2);
mElements3.push_back(bottom1);
mElements3.push_back(bottom2);
}
}

void Capsule::Draw() const {
mVAO->Bind();
mTexture->Bind();

mEBO1->Bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mElements1.size()), GL_UNSIGNED_INT, nullptr);

mEBO2->Bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mElements2.size()), GL_UNSIGNED_INT, nullptr);

mEBO3->Bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mElements3.size()), GL_UNSIGNED_INT, nullptr);

Texture::Unbind();
VAO::Unbind();
}

void Capsule::Delete() const {
mVAO->Delete();
mVBO->Delete();
mEBO1->Delete();
mEBO2->Delete();
mEBO3->Delete();
}

void Capsule::Scale(const glm::vec3 &v) {
mModel = glm::scale(mModel, v);
}

void Capsule::Translate(const glm::vec3 &v) {
mModel = glm::translate(mModel, v);
}

void Capsule::Rotate(float angle, const glm::vec3 &v) {
mModel = glm::rotate(mModel, angle, v);
}

void Capsule::Reset() {
mModel = glm::mat4(1.0f);
}

glm::mat4 Capsule::GetModel() const {
return mModel;
}
56 changes: 56 additions & 0 deletions Example16/src/Shapes/Capsule.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include "../EBO.hpp"
#include "../Texture.hpp"
#include "../VAO.hpp"
#include "../VBO.hpp"

#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include <glad/glad.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>

#include <memory>
#include <vector>

class Capsule {
public:
Capsule();
explicit Capsule(std::uint32_t sectors, std::uint32_t stacks);

void Draw() const;
void Delete() const;

[[nodiscard]] glm::mat4 GetModel() const;

void Scale(const glm::vec3 &v);
void Translate(const glm::vec3 &v);
void Rotate(float angle, const glm::vec3 &v);
void Reset();

private:
void Build(std::uint32_t sectors, std::uint32_t stacks);

struct Vertex {
glm::vec3 position;
glm::vec2 texture_coordinates;
};

std::vector<Vertex> mVertices;

// Index buffers and element vectors
std::vector<GLuint> mElements1;
std::vector<GLuint> mElements2;
std::vector<GLuint> mElements3;

glm::mat4 mModel{1.0f};

std::shared_ptr<VAO> mVAO;
std::shared_ptr<VBO<Vertex>> mVBO;
std::shared_ptr<EBO<GLuint>> mEBO1;
std::shared_ptr<EBO<GLuint>> mEBO2;
std::shared_ptr<EBO<GLuint>> mEBO3;
std::shared_ptr<Texture> mTexture;
};
2 changes: 1 addition & 1 deletion Example16/src/Shapes/Sphere.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "Sphere.hpp"

Sphere::Sphere() {
Build(32, 32);
Build(32, 16);

mVAO = VAO::Create();
mVBO = VBO<Vertex>::Create(mVertices);
Expand Down

0 comments on commit 2d6f6a3

Please sign in to comment.