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