Skip to content
This repository was archived by the owner on Jan 2, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.0.0)
project(learnopengl VERSION 0.1.0)

include(CTest)
enable_testing()

if(MSVC)
add_compile_options(/W4)
else()
add_compile_options(-Wall -Wextra -Wpedantic -Weffc++)
endif()

add_executable(learnopengl main.cpp IndexBuffer.cpp VertexBuffer.cpp VertexArray.cpp Shader.cpp Renderer.cpp Texture.cpp Camera.cpp Mesh.cpp Model.cpp CubeMap.cpp stb_image.cpp)
target_include_directories(learnopengl PRIVATE includes)
target_link_libraries(learnopengl PRIVATE GLEW glfw GL X11 dl assimp)
target_compile_features(learnopengl PRIVATE cxx_auto_type)
target_compile_features(learnopengl PRIVATE cxx_nullptr)
target_compile_features(learnopengl PRIVATE cxx_range_for)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
95 changes: 95 additions & 0 deletions 404_417_418_427_Kitchen_Simulation (Rollno Corrected)/Camera.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "Camera.hpp"

#define PLANE_Y -1.f

Camera::Camera(const glm::vec3 &position, const glm::vec3 &up, float yaw, float pitch)
: m_Position(position),
m_Up(up),
m_Yaw(yaw),
m_Pitch(pitch),
m_FOV(45.f)
{
updateCameraVectors();
}

Camera::Camera(float posX, float posY, float posZ, float upX, float upY, float upZ, float yaw, float pitch)
: m_Position(glm::vec3(posX, posY, posZ)),
m_Up(glm::vec3(upX, upY, upZ)),
m_Yaw(yaw),
m_Pitch(pitch),
m_FOV(45.f)
{
updateCameraVectors();
}
void Camera::ProcessKeyboard(const CameraMovement &direction, float deltaTime)
{
const float velocity = 2.5f * deltaTime;

switch (direction)
{
case CameraMovement::FORWARD:
m_Position += m_Front * velocity;
break;
case CameraMovement::BACKWARD:
m_Position -= m_Front * velocity;
break;
case CameraMovement::LEFT:
m_Position -= m_Right * velocity;
break;
case CameraMovement::RIGHT:
m_Position += m_Right * velocity;
break;
case CameraMovement::UP:
m_Position += m_Up * velocity;
break;
// For CameraMovement::DOWN
default:
m_Position -= m_Up * velocity;
}
if (m_Position.y <= PLANE_Y)
m_Position.y = PLANE_Y;
}

void Camera::ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch)
{
const float mouseSensitivity = 0.1f;
m_Yaw += xoffset * mouseSensitivity;
m_Pitch += yoffset * mouseSensitivity;

// Make sure that when pitch is out of bounds, screen doesn't get flipped
if (constrainPitch)
{
if (m_Pitch > 89.0f)
m_Pitch = 89.0f;
else if (m_Pitch < -89.0f)
m_Pitch = -89.0f;
}

// Update Front & Right Vectors using the updated Euler angles
updateCameraVectors();
}

void Camera::ProcessMouseScroll(float yoffset)
{
m_FOV -= yoffset;
if (m_FOV < 1.f)
m_FOV = 1.f;
else if (m_FOV > 45.f)
m_FOV = 45.f;
}

void Camera::updateCameraVectors()
{
// Calculate the new Front vector
m_Front = glm::normalize(
glm::vec3(
cos(glm::radians(m_Yaw)) * cos(glm::radians(m_Pitch)),
sin(glm::radians(m_Pitch)),
sin(glm::radians(m_Yaw)) * cos(glm::radians(m_Pitch))));

/*
Recalculate the right vector also
Normalize the vectors, because their length gets closer to 0 the more you look up or down which results in slower movement.
*/
m_Right = glm::normalize(glm::cross(m_Front, m_Up));
}
39 changes: 39 additions & 0 deletions 404_417_418_427_Kitchen_Simulation (Rollno Corrected)/CubeMap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <iostream>

#include "CubeMap.hpp"
#include "stb_image.h"

CubeMap::CubeMap(const std::vector<std::string> &faces)
{
glGenTextures(1, &m_RendererID);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_RendererID);

int width, height, nrChannels;
u_char *localBuffer;
stbi_set_flip_vertically_on_load(false);
for (uint i = 0; i < faces.size(); ++i)
{
/*
load and generate the texture
NOTE: Last argument to force the number of channels, **0 to not force**
*/
localBuffer = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
if (localBuffer)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, localBuffer);
stbi_image_free(localBuffer);
}
else
std::cerr << "Cubemap tex failed to load at path: " << faces[i] << std::endl;
}

// set the texture wrapping/filtering options (on the currently bound texture object)
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// Unbinding texture
Unbind();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "IndexBuffer.hpp"

IndexBuffer::IndexBuffer(const unsigned int *data, const unsigned int count)
: m_Count(count)
{
glGenBuffers(1, &m_RendererID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW);
}
68 changes: 68 additions & 0 deletions 404_417_418_427_Kitchen_Simulation (Rollno Corrected)/Mesh.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "Mesh.hpp"
#include "VertexBufferLayout.hpp"
#include "Renderer.hpp"

Mesh::Mesh(std::vector<Vertex> &vertices, std::vector<uint> &indices, const std::unordered_map<std::string, Texture> &texturesLoaded, std::vector<std::string> &textures)
: m_TexturesLoaded(texturesLoaded),
m_Vertices(vertices),
m_Indices(indices),
m_Textures(textures),
m_VA(),
m_IB(&indices[0], indices.size()),
/*
NOTE: Address of Vector and the address of first element of vector are different.
Also, sizeof(<vector>) is the size of the vector not containing data
*/
m_VB(&vertices[0], sizeof(Vertex) * vertices.size())
{
SetupMesh();
}

void Mesh::SetupMesh() const
{
VertexBufferLayout layout;

// For Vertex Positions
layout.Push<float>(3);

//For Vertex Normals
layout.Push<float>(3);

// For Vertex Texture Coords
layout.Push<float>(2);

// For Vertex Tangent
layout.Push<float>(3);

// For Vertex Bitangent
layout.Push<float>(3);

m_VA.AddBuffer(m_VB, layout);
}

void Mesh::Draw(Shader &shader) const
{
// bind appropriate textures
uint diffuseNr = 1;
uint specularNr = 1;

for (uint i = 0; i < m_Textures.size(); ++i)
{
const Texture &texture = m_TexturesLoaded.find(m_Textures[i])->second;
// retrieve texture number (the N in diffuse_textureN)
std::string number;
const std::string &textureType = texture.GetType();

if (textureType == "diffuse")
number = std::to_string(diffuseNr++);
else if (textureType == "specular")
number = std::to_string(specularNr++); // transfer unsigned int to stream
else
continue;
shader.SetUniform(("u_Material." + textureType + number).c_str(), static_cast<int>(i));
texture.Bind(i);
}

// Draw mesh
Renderer::Draw(m_VA, m_IB);
}
141 changes: 141 additions & 0 deletions 404_417_418_427_Kitchen_Simulation (Rollno Corrected)/Model.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <glm/vec3.hpp>
#include <glm/vec2.hpp>
#include <GL/glew.h>
#include "Model.hpp"

Model::Model(const std::string &path)
: m_Directory(path.substr(0, path.find_last_of("/"))) // retrieve the directory path of the filepath
{
// loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector.
// read file via ASSIMP
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(
path, aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_JoinIdenticalVertices);

// check for errors
if (!scene or scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE or !scene->mRootNode)
{
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
return;
}

// process ASSIMP's root node recursively
ProcessNode(scene->mRootNode, scene);
}

void Model::ProcessNode(const aiNode *node, const aiScene *scene)
{
// process each mesh located at the current node
for (uint i = 0; i < node->mNumMeshes; ++i)
{
// the node object only contains indices to index the actual objects in the scene.
// the scene contains all the data, node is just to keep stuff organized (like relations between nodes).
const aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
ProcessMesh(mesh, scene);
}
// after we've processed all of the meshes (if any) we then recursively process each of the children nodes
for (uint i = 0; i < node->mNumChildren; ++i)
ProcessNode(node->mChildren[i], scene);
}

void Model::ProcessMesh(const aiMesh *mesh, const aiScene *scene)
{
// data to fill
std::vector<Vertex> vertices;
vertices.reserve(mesh->mNumVertices);
std::vector<uint> indices;
std::vector<std::string> textures;

// Walk through each of the mesh's vertices
for (uint i = 0; i < mesh->mNumVertices; ++i)
{
Vertex vertex;
// aiVector is container for positions and normals of assimp which cannot be converted to glm::vec3 directly
// For positions
aiVector3D aiVector = mesh->mVertices[i];
vertex.Position = glm::vec3(aiVector.x, aiVector.y, aiVector.z);

// For normals
aiVector = mesh->mNormals[i];
vertex.Normal = glm::vec3(aiVector.x, aiVector.y, aiVector.z);

// For tangent
aiVector = mesh->mTangents[i];
vertex.Tangent = glm::vec3(aiVector.x, aiVector.y, aiVector.z);

// For bitangent
aiVector = mesh->mBitangents[i];
vertex.Bitangent = glm::vec3(aiVector.x, aiVector.y, aiVector.z);

// Texture Coordinates
if (mesh->mTextureCoords[0]) // check if the mesh contains texture cooordinates
{
/*
A vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
use models where a vertex can have multiple texture coordinates so we always take the first set (0).
*/
aiVector = mesh->mTextureCoords[0][i];
vertex.TexCoords = glm::vec2(aiVector.x, aiVector.y);
}
else
vertex.TexCoords = glm::vec2(0.f);

vertices.push_back(vertex);
}

// now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
for (uint i = 0; i < mesh->mNumFaces; ++i)
{
const aiFace &face = mesh->mFaces[i];
// retrieve all indices of the face and store them in the indices vector
for (uint j = 0; j < face.mNumIndices; ++j)
indices.push_back(face.mIndices[j]);
}

//process materials
const aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
/*
we assume a convention for sampler names in the shaders. Each diffuse texture should be named
as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
Same applies to other texture as the following list summarizes:
diffuse: texture_diffuseN
specular: texture_specularN
normal: texture_normalN
*/

//Diffuse Maps
LoadMaterialTextures(material, textures, aiTextureType_DIFFUSE, "diffuse");

// Specular Maps
LoadMaterialTextures(material, textures, aiTextureType_SPECULAR, "specular");

// Normal maps
// LoadMaterialTextures(material, textures, aiTextureType_HEIGHT, "normal");

// Height maps
// LoadMaterialTextures(material, textures, aiTextureType_AMBIENT, "height");

// return a mesh object created from the extracted mesh data
m_Meshes.emplace_back(vertices, indices, m_TexturesLoaded, textures);
}

void Model::LoadMaterialTextures(const aiMaterial *mat, std::vector<std::string> &textures, aiTextureType type, const char *typeName)
{
for (uint i = 0; i < mat->GetTextureCount(type); ++i)
{
aiString path;
mat->GetTexture(type, i, &path);
std::string pathString = path.C_Str();
const auto loadedTexture = m_TexturesLoaded.find(pathString);
if (loadedTexture == m_TexturesLoaded.end())
{
m_TexturesLoaded.emplace(std::piecewise_construct,
std::forward_as_tuple(pathString),
std::forward_as_tuple(m_Directory + '/' + pathString,
typeName));
}
textures.push_back(pathString);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# learnopengl
Loading