feat: assignment 2

This commit is contained in:
2025-10-13 15:04:53 +02:00
parent 986e31dbef
commit f981cee4e0
17 changed files with 649 additions and 56 deletions

56
.clang-format Normal file
View File

@@ -0,0 +1,56 @@
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -8
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignConsecutiveDeclarations: Consecutive
AlignConsecutiveMacros: Consecutive
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: Always
AllowShortBlocksOnASingleLine: Never
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: None
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: false
ColumnLimit: 80
Cpp11BracedListStyle: true
EmptyLineBeforeAccessModifier: Always
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentWidth: 8
InsertNewlineAtEOF: true
InsertTrailingCommas: None
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PackConstructorInitializers: NextLineOnly
PointerAlignment: Left
SortIncludes: Never
SpaceBeforeCaseColon: false
TabWidth: 8
UseTab: Always

64
.clang-tidy Normal file
View File

@@ -0,0 +1,64 @@
---
# Linux-style naming conventions for C++ projects
Checks: >
readability-identifier-naming,
readability-braces-around-statements,
readability-function-size,
modernize-use-nullptr,
modernize-use-override,
performance-*,
-modernize-use-trailing-return-type
CheckOptions:
# Classes and structs use CamelCase (C++ convention)
- { key: readability-identifier-naming.ClassCase, value: CamelCase }
- { key: readability-identifier-naming.StructCase, value: CamelCase }
- { key: readability-identifier-naming.EnumCase, value: CamelCase }
- { key: readability-identifier-naming.UnionCase, value: CamelCase }
# Functions and methods use snake_case (Linux style)
- { key: readability-identifier-naming.FunctionCase, value: lower_case }
- { key: readability-identifier-naming.MethodCase, value: lower_case }
# Member variables: snake_case with trailing underscore
- { key: readability-identifier-naming.PrivateMemberCase, value: lower_case }
- { key: readability-identifier-naming.PrivateMemberSuffix, value: '_' }
- { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case }
- { key: readability-identifier-naming.ProtectedMemberSuffix, value: '_' }
- { key: readability-identifier-naming.PublicMemberCase, value: lower_case }
# Parameters and local variables: snake_case
- { key: readability-identifier-naming.ParameterCase, value: lower_case }
- { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.LocalVariableCase, value: lower_case }
# Constants and macros: UPPER_CASE
- { key: readability-identifier-naming.ConstantCase, value: UPPER_CASE }
- { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE }
- { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }
- { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE }
# Global variables: snake_case with g_ prefix (optional, can remove prefix)
- { key: readability-identifier-naming.GlobalVariableCase, value: lower_case }
- { key: readability-identifier-naming.GlobalVariablePrefix, value: 'g_' }
# Namespaces: snake_case
- { key: readability-identifier-naming.NamespaceCase, value: lower_case }
# Template parameters: CamelCase
- { key: readability-identifier-naming.TypeTemplateParameterCase, value: CamelCase }
- { key: readability-identifier-naming.ValueTemplateParameterCase, value: lower_case }
# Typedef and type aliases: snake_case_t suffix (Linux style)
- { key: readability-identifier-naming.TypedefCase, value: lower_case }
- { key: readability-identifier-naming.TypedefSuffix, value: '_t' }
- { key: readability-identifier-naming.TypeAliasCase, value: lower_case }
- { key: readability-identifier-naming.TypeAliasSuffix, value: '_t' }
# Function size limits
- { key: readability-function-size.LineThreshold, value: 100 }
- { key: readability-function-size.StatementThreshold, value: 50 }
WarningsAsErrors: ''
HeaderFilterRegex: 'src/.*\.h$'
FormatStyle: file

41
src/camera.cpp Normal file
View File

@@ -0,0 +1,41 @@
#include "camera.h"
#include "state.h"
#include "../lib/glew/GL/glew.h"
#include "../lib/glm/gtc/matrix_transform.hpp"
Camera::Camera()
: projection_(glm::mat4(1.0f))
, viewport_(0, 0, 800, 600)
, clearColor_(0.0f, 0.0f, 0.0f)
{
}
void Camera::prepare()
{
// Set projection matrix
State::projectionMatrix = projection_;
// Calculate view matrix
// For a camera, we need the inverse transformation:
// View = inverse(Translation * Rotation)
// Which is: Rotation^-1 * Translation^-1
glm::mat4 view = glm::mat4(1.0f);
// Inverse rotation (rotate in opposite direction)
view = glm::rotate(view, -rotation_.z, glm::vec3(0.0f, 0.0f, 1.0f));
view = glm::rotate(view, -rotation_.y, glm::vec3(0.0f, 1.0f, 0.0f));
view = glm::rotate(view, -rotation_.x, glm::vec3(1.0f, 0.0f, 0.0f));
// Inverse translation (translate in opposite direction)
view = glm::translate(view, -position_);
State::viewMatrix = view;
// Set viewport
glViewport(viewport_.x, viewport_.y, viewport_.z, viewport_.w);
glScissor(viewport_.x, viewport_.y, viewport_.z, viewport_.w);
// Set clear color and clear buffers
glClearColor(clearColor_.r, clearColor_.g, clearColor_.b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

46
src/camera.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef CAMERA_H_
#define CAMERA_H_
#include "entity.h"
#include "../lib/glm/glm.hpp"
class Camera : public Entity {
public:
Camera();
const glm::mat4& getProjection() const
{
return projection_;
}
void setProjection(const glm::mat4& proj)
{
projection_ = proj;
}
const glm::ivec4& getViewport() const
{
return viewport_;
}
void setViewport(const glm::ivec4& vp)
{
viewport_ = vp;
}
const glm::vec3& getClearColor() const
{
return clearColor_;
}
void setClearColor(const glm::vec3& color)
{
clearColor_ = color;
}
void prepare();
private:
glm::mat4 projection_;
glm::ivec4 viewport_;
glm::vec3 clearColor_;
};
#endif // CAMERA_H_

13
src/entity.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "entity.h"
Entity::Entity()
: position_(0.0f, 0.0f, 0.0f)
, rotation_(0.0f, 0.0f, 0.0f)
, scale_(1.0f, 1.0f, 1.0f)
{
}
void Entity::move(const glm::vec3& vec)
{
position_ += vec;
}

55
src/entity.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef ENTITY_H_
#define ENTITY_H_
#include "../lib/glm/glm.hpp"
class Entity {
public:
Entity();
virtual ~Entity()
{
}
const glm::vec3& getPosition() const
{
return position_;
}
void setPosition(const glm::vec3& pos)
{
position_ = pos;
}
const glm::vec3& getRotation() const
{
return rotation_;
}
void setRotation(const glm::vec3& rot)
{
rotation_ = rot;
}
const glm::vec3& getScale() const
{
return scale_;
}
void setScale(const glm::vec3& scale)
{
scale_ = scale;
}
void move(const glm::vec3& vec);
virtual void update(float deltaTime)
{
}
virtual void draw()
{
}
protected:
glm::vec3 position_;
glm::vec3 rotation_;
glm::vec3 scale_;
};
#endif // ENTITY_H_

View File

@@ -2,9 +2,9 @@
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif*/
#include <iostream>
#include <vector>
#include <memory>
#include "../lib/glew/GL/glew.h"
#include "../lib/glfw/glfw3.h"
@@ -14,11 +14,18 @@
#include "vertex.h"
#include "shader.h"
#include "buffer.h"
#include "state.h"
#include "mesh.h"
#include "entity.h"
#include "model.h"
#include "camera.h"
#include "world.h"
#define SCREEN_WIDTH 800
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
int main() {
int main()
{
// Initialize OpenGL
if (!glfwInit()) {
std::cerr << "Failed to initialize glfw\n";
@@ -27,12 +34,13 @@ int main() {
glfwWindowHint(GLFW_RESIZABLE, false);
glfwWindowHint(GLFW_SAMPLES, 8);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Daniel Poveda", nullptr, nullptr);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT,
"Daniel Poveda", nullptr, nullptr);
if (win == nullptr) {
std::cerr << "Failed to create opengl window\n";
glfwTerminate();
@@ -43,68 +51,87 @@ int main() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
std::cout << "OpenGL initialized, version: " << glGetString(GL_VERSION) << "\n";
std::cout << "OpenGL initialized, version: " << glGetString(GL_VERSION)
<< "\n";
// Initialize GLEW
glewExperimental = GL_TRUE;
GLenum err = glewInit();
GLenum err = glewInit();
if (err != GLEW_OK) {
std::cerr << "Failed to initialize GLEW: " << glewGetErrorString(err) << "\n";
std::cerr << "Failed to initialize GLEW: "
<< glewGetErrorString(err) << "\n";
glfwTerminate();
return 1;
}
// Logic
std::vector<Vertex> vertices = {
{{0.0f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}},
{{-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}},
{{0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}
};
std::vector<uint16_t> indices = { 0, 1, 2 };
Buffer buffer(vertices, indices);
Shader shader("data/vertex.glsl", "data/fragment.glsl");
if (std::strlen(shader.getError()) > 0) {
std::cerr << "Failed to initialize shaders: " << shader.getError() << "\n";
// Initialize default shader
State::defaultShader =
std::make_shared<Shader>("data/vertex.glsl", "data/fragment.glsl");
if (std::strlen(State::defaultShader->getError()) > 0) {
std::cerr << "Failed to initialize shaders: "
<< State::defaultShader->getError() << "\n";
}
glm::mat4 projection = glm::perspective(glm::radians(45.0f), static_cast<float>(SCREEN_WIDTH) / SCREEN_HEIGHT, 0.1f, 100.0f);
//glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 6));
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 6), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
// Create world
World world;
// main loop
double angle = 0.0;
double lastTime = glfwGetTime();
while (!glfwWindowShouldClose(win) && !glfwGetKey(win, GLFW_KEY_ESCAPE)) {
// Delta
double delta_time = glfwGetTime() - lastTime;
lastTime = glfwGetTime();
// Create camera
auto camera = std::make_shared<Camera>();
camera->setPosition(glm::vec3(0.0f, 0.0f, 6.0f));
camera->setProjection(glm::perspective(
glm::radians(45.0f),
static_cast<float>(SCREEN_WIDTH) / SCREEN_HEIGHT, 0.1f, 100.0f));
camera->setViewport(glm::ivec4(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
camera->setClearColor(glm::vec3(0.1f, 0.1f, 0.1f));
world.addEntity(camera);
// Reset window
int screenWidth, screenHeight;
glfwGetWindowSize(win, &screenWidth, &screenHeight);
glViewport(0, 0, screenWidth, screenHeight);
// Create triangle mesh
std::vector<Vertex> vertices = {
{{0.0f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}},
{{-0.5f, -0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}},
{{0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}};
std::vector<uint16_t> indices = {0, 1, 2};
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
auto buffer = std::make_shared<Buffer>(vertices, indices);
auto mesh = std::make_shared<Mesh>();
mesh->addBuffer(buffer);
shader.Use();
// Logic
angle += 32.0 * delta_time;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
glm::mat4 model = glm::translate(glm::mat4(1.0), glm::vec3(-3.0f + static_cast<float>(col) * 3.0f, 0.0f, static_cast<float>(-row) * 3.0f));
model = glm::rotate(model, glm::radians(static_cast<float>(angle)), glm::vec3(0, 1, 0));
glm::mat4 mvp = projection * view * model;
Shader::setMat4(shader.getLocation("mvp"), mvp);
buffer.Draw(shader);
}
// Create 9 models in a 3x3 grid
std::vector<std::shared_ptr<Model>> models;
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
auto model = std::make_shared<Model>(mesh);
model->setPosition(
glm::vec3(-3.0f + static_cast<float>(col) * 3.0f,
0.0f, static_cast<float>(-row) * 3.0f));
models.push_back(model);
world.addEntity(model);
}
}
// Main loop
double angle = 0.0;
double lastTime = glfwGetTime();
while (!glfwWindowShouldClose(win)
&& !glfwGetKey(win, GLFW_KEY_ESCAPE)) {
// Delta time
double currentTime = glfwGetTime();
double deltaTime = currentTime - lastTime;
lastTime = currentTime;
// Update angle
angle += 32.0 * deltaTime;
// Update rotation for all models
for (auto& model : models) {
model->setRotation(glm::vec3(
0.0f, glm::radians(static_cast<float>(angle)),
0.0f));
}
// Update and draw world
world.update(static_cast<float>(deltaTime));
world.draw();
// Refresh screen
glfwSwapBuffers(win);
@@ -115,4 +142,4 @@ int main() {
glfwTerminate();
return 0;
}
}

33
src/mesh.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include "mesh.h"
#include "buffer.h"
#include "shader.h"
#include "state.h"
void Mesh::addBuffer(const std::shared_ptr<Buffer>& buffer,
const std::shared_ptr<Shader>& shader)
{
buffers_.push_back(buffer);
shaders_.push_back(shader);
}
void Mesh::draw()
{
// Calculate MVP matrix
glm::mat4 mvp =
State::projectionMatrix * State::viewMatrix * State::modelMatrix;
// Draw each buffer with its shader
for (size_t i = 0; i < buffers_.size(); ++i) {
// Use buffer's shader if available, otherwise use default
// shader
std::shared_ptr<Shader> shader =
shaders_[i] ? shaders_[i] : State::defaultShader;
if (shader) {
shader->Use();
int mvpLoc = shader->getLocation("mvp");
Shader::setMat4(mvpLoc, mvp);
buffers_[i]->Draw(*shader);
}
}
}

37
src/mesh.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef MESH_H_
#define MESH_H_
#include <memory>
#include <vector>
class Buffer;
class Shader;
class Mesh {
public:
Mesh() = default;
void addBuffer(const std::shared_ptr<Buffer>& buffer,
const std::shared_ptr<Shader>& shader = nullptr);
size_t getNumBuffers() const
{
return buffers_.size();
}
const std::shared_ptr<Buffer>& getBuffer(size_t index) const
{
return buffers_[index];
}
std::shared_ptr<Buffer>& getBuffer(size_t index)
{
return buffers_[index];
}
void draw();
private:
std::vector<std::shared_ptr<Buffer>> buffers_;
std::vector<std::shared_ptr<Shader>> shaders_;
};
#endif // MESH_H_

35
src/model.cpp Normal file
View File

@@ -0,0 +1,35 @@
#include "model.h"
#include "mesh.h"
#include "state.h"
#include "../lib/glm/gtc/matrix_transform.hpp"
Model::Model(const std::shared_ptr<Mesh>& mesh)
: mesh_(mesh)
{
}
void Model::draw()
{
if (!mesh_)
return;
// Build model matrix: Translation * Rotation * Scale
glm::mat4 model = glm::mat4(1.0f);
// Translation
model = glm::translate(model, position_);
// Rotation (applying X, Y, Z rotations)
model = glm::rotate(model, rotation_.x, glm::vec3(1.0f, 0.0f, 0.0f));
model = glm::rotate(model, rotation_.y, glm::vec3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, rotation_.z, glm::vec3(0.0f, 0.0f, 1.0f));
// Scale
model = glm::scale(model, scale_);
// Set the model matrix in State
State::modelMatrix = model;
// Draw the mesh
mesh_->draw();
}

19
src/model.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef MODEL_H_
#define MODEL_H_
#include "entity.h"
#include <memory>
class Mesh;
class Model : public Entity {
public:
Model(const std::shared_ptr<Mesh>& mesh);
virtual void draw() override;
private:
std::shared_ptr<Mesh> mesh_;
};
#endif // MODEL_H_

6
src/state.cpp Normal file
View File

@@ -0,0 +1,6 @@
#include "state.h"
std::shared_ptr<Shader> State::defaultShader = nullptr;
glm::mat4 State::projectionMatrix = glm::mat4(1.0f);
glm::mat4 State::viewMatrix = glm::mat4(1.0f);
glm::mat4 State::modelMatrix = glm::mat4(1.0f);

17
src/state.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef STATE_H_
#define STATE_H_
#include <memory>
#include "../lib/glm/glm.hpp"
class Shader;
class State {
public:
static std::shared_ptr<Shader> defaultShader;
static glm::mat4 projectionMatrix;
static glm::mat4 viewMatrix;
static glm::mat4 modelMatrix;
};
#endif // STATE_H_

58
src/world.cpp Normal file
View File

@@ -0,0 +1,58 @@
#include "world.h"
#include "entity.h"
#include "camera.h"
#include <algorithm>
void World::addEntity(const std::shared_ptr<Entity>& entity)
{
entities_.push_back(entity);
// Check if entity is a camera
std::shared_ptr<Camera> camera =
std::dynamic_pointer_cast<Camera>(entity);
if (camera) {
cameras_.push_back(camera);
}
}
void World::removeEntity(const std::shared_ptr<Entity>& entity)
{
// Remove from entities list
auto it = std::find(entities_.begin(), entities_.end(), entity);
if (it != entities_.end()) {
entities_.erase(it);
}
// Check if entity is a camera and remove from cameras list
std::shared_ptr<Camera> camera =
std::dynamic_pointer_cast<Camera>(entity);
if (camera) {
auto camIt =
std::find(cameras_.begin(), cameras_.end(), camera);
if (camIt != cameras_.end()) {
cameras_.erase(camIt);
}
}
}
void World::update(float deltaTime)
{
for (auto& entity : entities_) {
entity->update(deltaTime);
}
}
void World::draw()
{
// Draw for each camera
for (auto& camera : cameras_) {
// Prepare the camera (sets viewport, projection, view, clears
// screen)
camera->prepare();
// Draw all entities
for (auto& entity : entities_) {
entity->draw();
}
}
}

38
src/world.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef WORLD_H_
#define WORLD_H_
#include <memory>
#include <vector>
class Entity;
class Camera;
class World {
public:
World() = default;
void addEntity(const std::shared_ptr<Entity>& entity);
void removeEntity(const std::shared_ptr<Entity>& entity);
size_t getNumEntities() const
{
return entities_.size();
}
const std::shared_ptr<Entity>& getEntity(size_t index) const
{
return entities_[index];
}
std::shared_ptr<Entity>& getEntity(size_t index)
{
return entities_[index];
}
void update(float deltaTime);
void draw();
private:
std::vector<std::shared_ptr<Entity>> entities_;
std::vector<std::shared_ptr<Camera>> cameras_;
};
#endif // WORLD_H_

View File

@@ -160,15 +160,27 @@
<ClInclude Include="lib\glfw\glfw3.h" />
<ClInclude Include="lib\glfw\glfw3native.h" />
<ClInclude Include="src\buffer.h" />
<ClInclude Include="src\camera.h" />
<ClInclude Include="src\entity.h" />
<ClInclude Include="src\mesh.h" />
<ClInclude Include="src\model.h" />
<ClInclude Include="src\shader.h" />
<ClInclude Include="src\state.h" />
<ClInclude Include="src\vertex.h" />
<ClInclude Include="src\world.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="lib\glew\glew.c" />
<ClCompile Include="src\buffer.cpp" />
<ClCompile Include="src\camera.cpp" />
<ClCompile Include="src\entity.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\mesh.cpp" />
<ClCompile Include="src\model.cpp" />
<ClCompile Include="src\shader.cpp" />
<ClCompile Include="src\state.cpp" />
<ClCompile Include="src\vertex.cpp" />
<ClCompile Include="src\world.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="data\fragment.glsl" />

View File

@@ -42,6 +42,24 @@
<ClInclude Include="src\buffer.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\state.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\mesh.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\entity.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\model.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\camera.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\world.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\main.cpp">
@@ -59,6 +77,24 @@
<ClCompile Include="src\buffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\state.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\mesh.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\entity.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\model.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\world.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="data\fragment.glsl">