feat: assignment 2
This commit is contained in:
56
.clang-format
Normal file
56
.clang-format
Normal 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
64
.clang-tidy
Normal 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
41
src/camera.cpp
Normal 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
46
src/camera.h
Normal 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
13
src/entity.cpp
Normal 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
55
src/entity.h
Normal 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_
|
||||
139
src/main.cpp
139
src/main.cpp
@@ -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
33
src/mesh.cpp
Normal 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
37
src/mesh.h
Normal 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
35
src/model.cpp
Normal 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
19
src/model.h
Normal 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
6
src/state.cpp
Normal 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
17
src/state.h
Normal 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
58
src/world.cpp
Normal 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
38
src/world.h
Normal 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_
|
||||
@@ -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" />
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user