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_ | ||||||
							
								
								
									
										119
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								src/main.cpp
									
									
									
									
									
								
							| @@ -2,9 +2,9 @@ | |||||||
| #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") | #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") | ||||||
| #endif*/ | #endif*/ | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <memory> | ||||||
|  |  | ||||||
| #include "../lib/glew/GL/glew.h" | #include "../lib/glew/GL/glew.h" | ||||||
| #include "../lib/glfw/glfw3.h" | #include "../lib/glfw/glfw3.h" | ||||||
| @@ -14,11 +14,18 @@ | |||||||
| #include "vertex.h" | #include "vertex.h" | ||||||
| #include "shader.h" | #include "shader.h" | ||||||
| #include "buffer.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 | #define SCREEN_HEIGHT 600 | ||||||
|  |  | ||||||
| int main() { | int main() | ||||||
|  | { | ||||||
| 	// Initialize OpenGL | 	// Initialize OpenGL | ||||||
| 	if (!glfwInit()) { | 	if (!glfwInit()) { | ||||||
| 		std::cerr << "Failed to initialize glfw\n"; | 		std::cerr << "Failed to initialize glfw\n"; | ||||||
| @@ -32,7 +39,8 @@ int main() { | |||||||
| 	// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | 	// glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | ||||||
| 	// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | 	// glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | ||||||
|  |  | ||||||
| 	GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Daniel Poveda", nullptr, nullptr); | 	GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, | ||||||
|  | 					   "Daniel Poveda", nullptr, nullptr); | ||||||
| 	if (win == nullptr) { | 	if (win == nullptr) { | ||||||
| 		std::cerr << "Failed to create opengl window\n"; | 		std::cerr << "Failed to create opengl window\n"; | ||||||
| 		glfwTerminate(); | 		glfwTerminate(); | ||||||
| @@ -43,69 +51,88 @@ int main() { | |||||||
| 	glEnable(GL_DEPTH_TEST); | 	glEnable(GL_DEPTH_TEST); | ||||||
| 	glEnable(GL_SCISSOR_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 | 	// Initialize GLEW | ||||||
| 	glewExperimental = GL_TRUE; | 	glewExperimental = GL_TRUE; | ||||||
| 	GLenum err	 = glewInit(); | 	GLenum err	 = glewInit(); | ||||||
| 	if (err != GLEW_OK) { | 	if (err != GLEW_OK) { | ||||||
| 		std::cerr << "Failed to initialize GLEW: " << glewGetErrorString(err) << "\n"; | 		std::cerr << "Failed to initialize GLEW: " | ||||||
|  | 			  << glewGetErrorString(err) << "\n"; | ||||||
| 		glfwTerminate(); | 		glfwTerminate(); | ||||||
| 		return 1; | 		return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Logic | 	// 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"; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Create world | ||||||
|  | 	World world; | ||||||
|  |  | ||||||
|  | 	// 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); | ||||||
|  |  | ||||||
|  | 	// Create triangle mesh | ||||||
| 	std::vector<Vertex> vertices = { | 	std::vector<Vertex> vertices = { | ||||||
| 	    {{0.0f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}}, | 	    {{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}, {0.0f, 0.0f, 1.0f}}, | ||||||
| 		{{0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}  | 	    {{0.5f, -0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}}}; | ||||||
| 	}; |  | ||||||
| 	std::vector<uint16_t> indices = {0, 1, 2}; | 	std::vector<uint16_t> indices = {0, 1, 2}; | ||||||
|  |  | ||||||
| 	Buffer buffer(vertices, indices); | 	auto buffer = std::make_shared<Buffer>(vertices, indices); | ||||||
| 	Shader shader("data/vertex.glsl", "data/fragment.glsl"); | 	auto mesh   = std::make_shared<Mesh>(); | ||||||
| 	if (std::strlen(shader.getError()) > 0) { | 	mesh->addBuffer(buffer); | ||||||
| 		std::cerr << "Failed to initialize shaders: " << shader.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)); |  | ||||||
|  |  | ||||||
| 	// 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(); |  | ||||||
|  |  | ||||||
| 		// Reset window |  | ||||||
| 		int screenWidth, screenHeight; |  | ||||||
| 		glfwGetWindowSize(win, &screenWidth, &screenHeight); |  | ||||||
| 		glViewport(0, 0, screenWidth, screenHeight); |  | ||||||
|  |  | ||||||
| 		glClearColor(0.1f, 0.1f, 0.1f, 1.0f); |  | ||||||
| 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |  | ||||||
|  |  | ||||||
| 		shader.Use(); |  | ||||||
|  |  | ||||||
| 		// Logic |  | ||||||
| 		angle += 32.0 * delta_time; |  | ||||||
|  |  | ||||||
|  | 	// Create 9 models in a 3x3 grid | ||||||
|  | 	std::vector<std::shared_ptr<Model>> models; | ||||||
| 	for (int row = 0; row < 3; ++row) { | 	for (int row = 0; row < 3; ++row) { | ||||||
| 		for (int col = 0; col < 3; ++col) { | 		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)); | 			auto model = std::make_shared<Model>(mesh); | ||||||
| 				model = glm::rotate(model, glm::radians(static_cast<float>(angle)), glm::vec3(0, 1, 0)); | 			model->setPosition( | ||||||
|  | 			    glm::vec3(-3.0f + static_cast<float>(col) * 3.0f, | ||||||
| 				glm::mat4 mvp = projection * view * model; | 				      0.0f, static_cast<float>(-row) * 3.0f)); | ||||||
|  | 			models.push_back(model); | ||||||
| 				Shader::setMat4(shader.getLocation("mvp"), mvp); | 			world.addEntity(model); | ||||||
|  |  | ||||||
| 				buffer.Draw(shader); |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// 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 | 		// Refresh screen | ||||||
| 		glfwSwapBuffers(win); | 		glfwSwapBuffers(win); | ||||||
| 		glfwPollEvents(); | 		glfwPollEvents(); | ||||||
|   | |||||||
							
								
								
									
										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\glfw3.h" /> | ||||||
|     <ClInclude Include="lib\glfw\glfw3native.h" /> |     <ClInclude Include="lib\glfw\glfw3native.h" /> | ||||||
|     <ClInclude Include="src\buffer.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\shader.h" /> | ||||||
|  |     <ClInclude Include="src\state.h" /> | ||||||
|     <ClInclude Include="src\vertex.h" /> |     <ClInclude Include="src\vertex.h" /> | ||||||
|  |     <ClInclude Include="src\world.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="lib\glew\glew.c" /> |     <ClCompile Include="lib\glew\glew.c" /> | ||||||
|     <ClCompile Include="src\buffer.cpp" /> |     <ClCompile Include="src\buffer.cpp" /> | ||||||
|  |     <ClCompile Include="src\camera.cpp" /> | ||||||
|  |     <ClCompile Include="src\entity.cpp" /> | ||||||
|     <ClCompile Include="src\main.cpp" /> |     <ClCompile Include="src\main.cpp" /> | ||||||
|  |     <ClCompile Include="src\mesh.cpp" /> | ||||||
|  |     <ClCompile Include="src\model.cpp" /> | ||||||
|     <ClCompile Include="src\shader.cpp" /> |     <ClCompile Include="src\shader.cpp" /> | ||||||
|  |     <ClCompile Include="src\state.cpp" /> | ||||||
|     <ClCompile Include="src\vertex.cpp" /> |     <ClCompile Include="src\vertex.cpp" /> | ||||||
|  |     <ClCompile Include="src\world.cpp" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="data\fragment.glsl" /> |     <None Include="data\fragment.glsl" /> | ||||||
|   | |||||||
| @@ -42,6 +42,24 @@ | |||||||
|     <ClInclude Include="src\buffer.h"> |     <ClInclude Include="src\buffer.h"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClInclude> |     </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> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ClCompile Include="src\main.cpp"> |     <ClCompile Include="src\main.cpp"> | ||||||
| @@ -59,6 +77,24 @@ | |||||||
|     <ClCompile Include="src\buffer.cpp"> |     <ClCompile Include="src\buffer.cpp"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </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> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <None Include="data\fragment.glsl"> |     <None Include="data\fragment.glsl"> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user