Compare commits
	
		
			5 Commits
		
	
	
		
			adf2331ab1
			...
			f37175a01e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| f37175a01e | |||
| c62f3615d4 | |||
| 3e75406783 | |||
| 65ae892951 | |||
| f0984b6117 | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @ -31,3 +31,6 @@ | |||||||
| [submodule "libs/entt"] | [submodule "libs/entt"] | ||||||
| 	path = libs/entt | 	path = libs/entt | ||||||
| 	url = https://github.com/skypjack/entt.git | 	url = https://github.com/skypjack/entt.git | ||||||
|  | [submodule "libs/guizmo"] | ||||||
|  | 	path = libs/guizmo | ||||||
|  | 	url = https://github.com/CedricGuillemet/ImGuizmo.git | ||||||
|  | |||||||
| @ -60,3 +60,4 @@ project "BarinkEngine" | |||||||
|   } |   } | ||||||
|  |  | ||||||
| include('../ImGui') | include('../ImGui') | ||||||
|  | include("../ImGuizmo") | ||||||
| @ -1,18 +1,19 @@ | |||||||
| #include "BarinkEngine.h" | #include "BarinkEngine.h" | ||||||
|  |  | ||||||
| EngineStatistics ES; | extern EngineStatistics ES; | ||||||
| BarinkEngine::Renderer renderer; | BarinkEngine::Renderer renderer; | ||||||
|  | const unsigned int MS_PER_UPDATE = 2; | ||||||
| int main(int argc, char* argv[]) { | int main(int argc, char* argv[]) { | ||||||
| 	// Setup performance sampler  | 	// Setup performance sampler  | ||||||
| 	PerfomanceSamplerInit(); | 	EngineInstrumentation::PerfomanceSamplerInit(); | ||||||
|  |  | ||||||
| 	// Startup services  | 	// Startup services  | ||||||
| 	BarinkWindow MainWindow =  BarinkWindow(800, 600); | 	BarinkWindow MainWindow =  BarinkWindow(1200, 700); | ||||||
|  |  | ||||||
| 	renderer = BarinkEngine::Renderer(); | 	renderer = BarinkEngine::Renderer(); | ||||||
| 	InputSystem = BarinkEngine::InputManager(); | 	InputSystem = BarinkEngine::InputManager(); | ||||||
| 	ES = EngineStatistics(); |  | ||||||
|  |  | ||||||
|  | 	ES = EngineStatistics{}; | ||||||
| 	InputSystem.attach(&MainWindow); | 	InputSystem.attach(&MainWindow); | ||||||
|  |  | ||||||
| 	GUIManager GUISystem = GUIManager(&MainWindow); | 	GUIManager GUISystem = GUIManager(&MainWindow); | ||||||
| @ -20,26 +21,65 @@ int main(int argc, char* argv[]) { | |||||||
| 	glEnable(GL_DEPTH_TEST); | 	glEnable(GL_DEPTH_TEST); | ||||||
|  |  | ||||||
| 	// First call to setup game | 	// First call to setup game | ||||||
|  | 	{ | ||||||
|  | 		PerfSampler("Start"); | ||||||
| 		Start(); | 		Start(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	double previous = glfwGetTime(); | ||||||
|  | 	double lag = 0.0; | ||||||
|  |  | ||||||
| 	// Runtime loop | 	// Runtime loop | ||||||
| 	while (!MainWindow.WindowShouldClose()) { | 	while (!MainWindow.WindowShouldClose())  | ||||||
| 		SamplePerformance(); | 	{ | ||||||
|  | 	 | ||||||
|  | 		double current = glfwGetTime(); | ||||||
|  | 		double elapsed = current - previous; | ||||||
|  | 		previous = current; | ||||||
|  | 		lag += elapsed; | ||||||
|  |  | ||||||
|  | 		//EngineInstrumentation::Update(); // Todo this does nothing right now and is therefor disabled | ||||||
|  |  | ||||||
| 		// Execute main logic  | 		// Execute main logic  | ||||||
|  | 		{ | ||||||
|  | 			PerfSampler("PollEvents"); | ||||||
| 			InputSystem.PollEvents(); | 			InputSystem.PollEvents(); | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		{ | ||||||
|  | 			PerfSampler("Update"); | ||||||
|  | 			while (lag >= MS_PER_UPDATE) { | ||||||
| 				Update(); | 				Update(); | ||||||
|  | 				lag -= MS_PER_UPDATE; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		{ | ||||||
|  | 			PerfSampler("Render"); | ||||||
|  | 			Render(); | ||||||
|  | 		} | ||||||
|  | 		 | ||||||
|  | 		{ | ||||||
|  | 			PerfSampler("GUI-Render"); | ||||||
| 			GUISystem.Render(); | 			GUISystem.Render(); | ||||||
|  | 		} | ||||||
| 		 | 		 | ||||||
|  |  | ||||||
|  | 		{ | ||||||
|  | 			PerfSampler("BufferSwap"); | ||||||
| 			MainWindow.SwapBuffers(); | 			MainWindow.SwapBuffers(); | ||||||
|  |  | ||||||
| 			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Shutdown game | 	// Shutdown game | ||||||
|  | 	{ | ||||||
|  | 		PerfSampler("Stop"); | ||||||
| 		Stop(); | 		Stop(); | ||||||
|  | 	} | ||||||
| 	 | 	 | ||||||
| 	// Shutdown Services | 	// Shutdown Services | ||||||
|  |  | ||||||
|  | |||||||
| @ -20,5 +20,6 @@ | |||||||
| extern BarinkEngine::Renderer renderer; | extern BarinkEngine::Renderer renderer; | ||||||
| extern void Start(); | extern void Start(); | ||||||
| extern void Update(); | extern void Update(); | ||||||
|  | extern void Render(); | ||||||
| extern void ImmediateGraphicsDraw(); | extern void ImmediateGraphicsDraw(); | ||||||
| extern void Stop(); | extern void Stop(); | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| #include "imgui.h" | #include "imgui.h" | ||||||
| #include "backends/imgui_impl_opengl3.h" | #include "backends/imgui_impl_opengl3.h" | ||||||
| #include <backends/imgui_impl_glfw.h> | #include <backends/imgui_impl_glfw.h> | ||||||
|  | #include "../../libs/guizmo/ImGuizmo.h" | ||||||
| #include "../BarinkEngine.h" | #include "../BarinkEngine.h" | ||||||
|  |  | ||||||
| GUIManager::GUIManager(BarinkWindow* window) | GUIManager::GUIManager(BarinkWindow* window) | ||||||
| @ -35,10 +36,17 @@ void GUIManager::Render() | |||||||
|  |  | ||||||
|     ImGui::NewFrame(); |     ImGui::NewFrame(); | ||||||
|  |  | ||||||
|     ImGui::Begin("##App"); |     ImGuizmo::SetOrthographic(true); | ||||||
|  |     ImGuizmo::BeginFrame(); | ||||||
|  |   | ||||||
|  |      | ||||||
|  |  | ||||||
|     ImmediateGraphicsDraw(); |     ImmediateGraphicsDraw(); | ||||||
|     ImGui::End(); |    | ||||||
|  |      | ||||||
|  |  | ||||||
|  |     ImGui::EndFrame(); | ||||||
|  |  | ||||||
|  |  | ||||||
|     ImGui::Render(); |     ImGui::Render(); | ||||||
|     ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); |     ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); | ||||||
|  | |||||||
| @ -1,15 +1,15 @@ | |||||||
| #include "Buffer.h" | #include "Buffer.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| int GpuBuffer::getBufferID() { | int Buffer::getBufferID() { | ||||||
| 	return id; | 	return id; | ||||||
| } | } | ||||||
|  |  | ||||||
| void GpuBuffer::createBuffer() { | void Buffer::createBuffer() { | ||||||
| 	glGenBuffers(1, (GLuint*) &id); | 	glGenBuffers(1, (GLuint*) &id); | ||||||
| } | } | ||||||
|  |  | ||||||
| void GpuBuffer::setBufferData(void* data, size_t dataSize, bool elementBuffer = false ) { | void Buffer::setBufferData(void* data, size_t dataSize, bool elementBuffer = false ) { | ||||||
| 	 | 	 | ||||||
| 	if (elementBuffer) { | 	if (elementBuffer) { | ||||||
| 		glBufferData(GL_ELEMENT_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); | 		glBufferData(GL_ELEMENT_ARRAY_BUFFER, dataSize, data, GL_STATIC_DRAW); | ||||||
| @ -21,7 +21,7 @@ void GpuBuffer::setBufferData(void* data, size_t dataSize, bool elementBuffer = | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void GpuBuffer::Bind(bool elementBuffer = false ) { | void Buffer::Bind(bool elementBuffer = false ) { | ||||||
| 	if (elementBuffer) { | 	if (elementBuffer) { | ||||||
| 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); | 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id); | ||||||
|  |  | ||||||
| @ -32,7 +32,7 @@ void GpuBuffer::Bind(bool elementBuffer = false ) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void GpuBuffer::Unbind(bool elementBuffer = false) { | void Buffer::Unbind(bool elementBuffer = false) { | ||||||
| 	if (elementBuffer) { | 	if (elementBuffer) { | ||||||
| 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | ||||||
| 	} | 	} | ||||||
| @ -42,6 +42,6 @@ void GpuBuffer::Unbind(bool elementBuffer = false) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void GpuBuffer::Delete() { | void Buffer::Delete() { | ||||||
| 	glDeleteBuffers(1, (GLuint*) &id); | 	glDeleteBuffers(1, (GLuint*) &id); | ||||||
| } | } | ||||||
| @ -1,8 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| #include <glad/glad.h> | #include <glad/glad.h> | ||||||
| class GpuBuffer { | class Buffer { | ||||||
| private: |  | ||||||
| 	unsigned int id; |  | ||||||
| public: | public: | ||||||
|  |  | ||||||
| 	int getBufferID(); | 	int getBufferID(); | ||||||
| @ -16,4 +15,7 @@ public: | |||||||
|  |  | ||||||
| 	void Delete(); | 	void Delete(); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	unsigned int id; | ||||||
|  |  | ||||||
| }; | }; | ||||||
| @ -9,25 +9,45 @@ Framebuffer::Framebuffer() | |||||||
| 	// Create a colour texture! | 	// Create a colour texture! | ||||||
| 	glGenTextures(1, &ColourAttachment); | 	glGenTextures(1, &ColourAttachment); | ||||||
| 	glBindTexture(GL_TEXTURE_2D, ColourAttachment); | 	glBindTexture(GL_TEXTURE_2D, ColourAttachment); | ||||||
| 	glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); |  | ||||||
|  | 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); | ||||||
|  |  | ||||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||||
| 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||||||
| 	 | 	 | ||||||
|  | 	glBindTexture(GL_TEXTURE_2D, 0); | ||||||
|  |  | ||||||
| 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColourAttachment, 0); | 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColourAttachment, 0); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	// Create a depth buffer  | ||||||
|  | 	glGenTextures(1, &DepthAttachment); | ||||||
|  | 	glBindTexture(GL_TEXTURE_2D, DepthAttachment); | ||||||
|  |  | ||||||
|  | 	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); | ||||||
|  | 	 | ||||||
| 	glBindTexture(GL_TEXTURE_2D, 0); | 	glBindTexture(GL_TEXTURE_2D, 0); | ||||||
|  |  | ||||||
| 	// Create a depth buffer  | 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, DepthAttachment, 0); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	* // Render buffer  | ||||||
| 		glGenRenderbuffers(1, &DepthAttachment); | 		glGenRenderbuffers(1, &DepthAttachment); | ||||||
| 		glBindRenderbuffer(GL_RENDERBUFFER, DepthAttachment); | 		glBindRenderbuffer(GL_RENDERBUFFER, DepthAttachment); | ||||||
|  |  | ||||||
| 		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600); | 		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600); | ||||||
|  |  | ||||||
| 	glFramebufferRenderbuffer(GL_RENDERBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthAttachment); |  | ||||||
|  |  | ||||||
| 		glBindRenderbuffer(GL_RENDERBUFFER, 0); | 		glBindRenderbuffer(GL_RENDERBUFFER, 0); | ||||||
| 		 | 		 | ||||||
|  | 		glFramebufferRenderbuffer(GL_RENDERBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthAttachment); | ||||||
|  |  | ||||||
|  | 	*/ | ||||||
|  | 	 | ||||||
|  | 	 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (!glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) | 	if (!glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) | ||||||
| @ -39,6 +59,8 @@ Framebuffer::Framebuffer() | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	glBindFramebuffer(GL_FRAMEBUFFER, 0); | 	glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||||
|  | 	 | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| Framebuffer::~Framebuffer()  | Framebuffer::~Framebuffer()  | ||||||
|  | |||||||
| @ -8,13 +8,14 @@ public: | |||||||
| 	Framebuffer(); | 	Framebuffer(); | ||||||
| 	~Framebuffer(); | 	~Framebuffer(); | ||||||
|  |  | ||||||
| 	unsigned int GetId() { return Id; } | 	GLuint GetId() { return Id; } | ||||||
| 	unsigned int GetColourAttachment() { return ColourAttachment; } | 	GLuint GetColourAttachment() { return ColourAttachment; } | ||||||
|  | 	GLuint GetDepthAttachment() { return DepthAttachment; } | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	unsigned int Id = 0; | 	GLuint Id = 0; | ||||||
| 	unsigned int ColourAttachment = 0; | 	GLuint ColourAttachment = 0; | ||||||
| 	unsigned int DepthAttachment = 0; | 	GLuint DepthAttachment = 0; | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
| }; | }; | ||||||
							
								
								
									
										31
									
								
								BarinkEngine/src/Graphics/Memory/UniformBuffer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								BarinkEngine/src/Graphics/Memory/UniformBuffer.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #include "UniformBuffer.h" | ||||||
|  | #include <glad/glad.h> | ||||||
|  | UniformBuffer::UniformBuffer(unsigned int size) | ||||||
|  | { | ||||||
|  | 	glGenBuffers(1, &Id ); | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, Id); | ||||||
|  | 	glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | UniformBuffer::~UniformBuffer()  | ||||||
|  | { | ||||||
|  | 	glDeleteBuffers(1, &Id); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void UniformBuffer::setData( unsigned int offset , unsigned int size , void* data) | ||||||
|  | { | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, Id); | ||||||
|  | 	glBufferSubData(GL_ARRAY_BUFFER, offset , size, data); | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void UniformBuffer::setDescriptor(unsigned int index, unsigned int size , unsigned int stride, void* pointer) | ||||||
|  | { | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, Id); | ||||||
|  | 	glVertexAttribPointer(index, size, GL_FLOAT, GL_FALSE, stride, pointer); | ||||||
|  | 	glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								BarinkEngine/src/Graphics/Memory/UniformBuffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								BarinkEngine/src/Graphics/Memory/UniformBuffer.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | class UniformBuffer { | ||||||
|  | public: | ||||||
|  |  | ||||||
|  | 	UniformBuffer (unsigned int size); | ||||||
|  | 	~UniformBuffer(); | ||||||
|  | 	void setData(unsigned int offset, unsigned int size, void* data); | ||||||
|  | 	void setDescriptor(unsigned int index, unsigned int size, unsigned int stride, void* pointer); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	unsigned int Id; | ||||||
|  |  | ||||||
|  | }; | ||||||
| @ -22,8 +22,8 @@ private: | |||||||
| 	std::vector<unsigned int > indices; | 	std::vector<unsigned int > indices; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	GpuBuffer vertexBuffer; | 	Buffer vertexBuffer; | ||||||
| 	GpuBuffer elementBuffer; | 	Buffer elementBuffer; | ||||||
|  |  | ||||||
| 	VertexArray VAO; | 	VertexArray VAO; | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| #include "../Graphics/Memory/VertexArray.h" | #include "../Graphics/Memory/VertexArray.h" | ||||||
| #include "../Graphics/Memory/Buffer.h" | #include "../Graphics/Memory/Buffer.h" | ||||||
| #include <glad/glad.h> | #include <glad/glad.h> | ||||||
|  | #include <glm/gtc/type_precision.hpp> | ||||||
| float Angle = 0.0; | float Angle = 0.0; | ||||||
| Camera cam = Camera(glm::vec3(12.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f); | Camera cam = Camera(glm::vec3(12.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 90.0f); | ||||||
| glm::mat4 projection = glm::perspective(glm::radians(cam.Zoom), (800.0f / 600.0f), 0.001f, 100.0f); | glm::mat4 projection = glm::perspective(glm::radians(cam.Zoom), (800.0f / 600.0f), 0.001f, 100.0f); | ||||||
| @ -16,8 +16,8 @@ void BarinkEngine::Renderer::Prepare(Scene& scene ) { | |||||||
| 	auto group = scene.getReg().view<BarinkEngine::Render3DComponent>(); | 	auto group = scene.getReg().view<BarinkEngine::Render3DComponent>(); | ||||||
| 	group.each([](auto enity, BarinkEngine::Render3DComponent& renderComponent) { | 	group.each([](auto enity, BarinkEngine::Render3DComponent& renderComponent) { | ||||||
| 		VertexArray va = VertexArray(); | 		VertexArray va = VertexArray(); | ||||||
| 		GpuBuffer vertexBuffer = GpuBuffer(); | 		Buffer vertexBuffer = Buffer(); | ||||||
| 		GpuBuffer elementBuffer = GpuBuffer(); | 		Buffer elementBuffer = Buffer(); | ||||||
|  |  | ||||||
| 		va.Create(); | 		va.Create(); | ||||||
| 		va.Bind(); | 		va.Bind(); | ||||||
| @ -45,24 +45,39 @@ void BarinkEngine::Renderer::Prepare(Scene& scene ) { | |||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| void BarinkEngine::Renderer::Render(Scene& scene) | void BarinkEngine::Renderer::Render(Scene& scene) | ||||||
| { | { | ||||||
| 	auto group = scene.getReg().view<TransformComponent, Render3DComponent>(); | 	auto group = scene.getReg().view<TransformComponent, Render3DComponent>(); | ||||||
| 	group.each([](auto entity , TransformComponent& trans, Render3DComponent& renderComponent)  | 	group.each([&](auto entity , TransformComponent& trans, Render3DComponent& renderComponent)  | ||||||
| 		{ | 		{ | ||||||
| 			 |  | ||||||
| 		glBindVertexArray(renderComponent.VAO); | 		glBindVertexArray(renderComponent.VAO); | ||||||
| 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderComponent.IBO); | 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, renderComponent.IBO); | ||||||
|  |  | ||||||
| 		renderComponent.shader.Use(); | 		renderComponent.shader.Use(); | ||||||
|  |  | ||||||
| 		renderComponent.shader.setUniformVec3("Color", renderComponent.color); | 		auto lights = scene.getReg().view<LightComponent>(); | ||||||
|  | 		lights.each([&](auto entity, LightComponent& light) { | ||||||
|  | 		  	renderComponent.shader.setUniformVec3("lighting.color", light.Color); | ||||||
|  | 			renderComponent.shader.setUniformFloat("lighting.strength", light.Strength); | ||||||
|  | 		}); | ||||||
|  |  | ||||||
| 		renderComponent.shader.setUniformMat4("M", trans.transform); |  | ||||||
|  | 		glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), trans.Rotation.x, glm::vec3(1.0f, 0.0f, 0.0f)); | ||||||
|  | 		rotation *= glm::rotate(glm::mat4(1.0f), trans.Rotation.y, glm::vec3(0.0f, 1.0f, 0.0f)); | ||||||
|  | 		rotation *= glm::rotate(glm::mat4(1.0f), trans.Rotation.z, glm::vec3(0.0f, 0.0f, 1.0f)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), trans.Position) * glm::scale(glm::mat4(1.0f), trans.Scale) *rotation; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		renderComponent.shader.setUniformVec3("Color", renderComponent.color); | ||||||
|  | 		renderComponent.shader.setUniformMat4("M", modelMatrix); | ||||||
| 		renderComponent.shader.setUniformMat4("V", cam.GetViewMatrix()); | 		renderComponent.shader.setUniformMat4("V", cam.GetViewMatrix()); | ||||||
| 		renderComponent.shader.setUniformMat4("P", projection); | 		renderComponent.shader.setUniformMat4("P", projection); | ||||||
|  |  | ||||||
|  | 		//std::cout << "Draw " << renderComponent.mesh.elements.size() << " elements" << std::endl; | ||||||
| 		glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(renderComponent.mesh.elements.size()) , | 		glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(renderComponent.mesh.elements.size()) , | ||||||
| 			GL_UNSIGNED_INT, NULL); | 			GL_UNSIGNED_INT, NULL); | ||||||
|  |  | ||||||
| @ -71,5 +86,17 @@ void BarinkEngine::Renderer::Render(Scene& scene) | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void Render(Framebuffer& framebuffer) | void BarinkEngine::Renderer::Render(Framebuffer& framebuffer, Scene& scene) | ||||||
| {} | { | ||||||
|  |  | ||||||
|  | 	glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.GetId()); | ||||||
|  |  | ||||||
|  | 	glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||||
|  | 	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||||
|  |  | ||||||
|  | 	Render(scene); | ||||||
|  | 	glBindFramebuffer(GL_FRAMEBUFFER, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -22,6 +22,6 @@ namespace BarinkEngine { | |||||||
| 		void Prepare(Scene& scene); | 		void Prepare(Scene& scene); | ||||||
| 		void Render(Scene& scene ); | 		void Render(Scene& scene ); | ||||||
|  |  | ||||||
| 		void Render(Framebuffer& framebuffer); | 		void Render(Framebuffer& framebuffer, Scene& scene); | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										70
									
								
								BarinkEngine/src/PerfCounter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								BarinkEngine/src/PerfCounter.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | #include "PerfCounter.h" | ||||||
|  | #include <imgui.h> | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  | EngineStatistics ES; | ||||||
|  |  | ||||||
|  | uint64_t EngineInstrumentation::GetPrecisionTime() { | ||||||
|  | 	using namespace std::chrono; // REMINDER: This is kinda ugly but safes line width | ||||||
|  | 	return duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EngineInstrumentation::PerfomanceSamplerInit() { | ||||||
|  | 	ES.frames = 0; | ||||||
|  | 	//EngineInstrumentation::lastSampleTime = GetPrecisionTime(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void EngineInstrumentation::Update() { | ||||||
|  | /* | ||||||
|  | uint64_t MilliSecondsPast = GetPrecisionTime() - EngineInstrumentation::lastSampleTime; | ||||||
|  |  | ||||||
|  | 	if (MilliSecondsPast >= 1000) { | ||||||
|  |  | ||||||
|  | 		ES.frameTime = (float)1000 / ES.frames; | ||||||
|  | 		ES.FPS = ES.frames; | ||||||
|  | 		ES.frames = 0; | ||||||
|  | 		//EngineInstrumentation::lastSampleTime = GetPrecisionTime(); | ||||||
|  | 	} | ||||||
|  | */	 | ||||||
|  | 	 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void EngineInstrumentation::ShowStats() { | ||||||
|  | 	ImGui::Begin("Statistics", false, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize); | ||||||
|  |  | ||||||
|  | 	ImGui::Text("FPS: %i", ES.FPS); | ||||||
|  | 	ImGui::Text("Frame Time: %f", ES.frameTime); | ||||||
|  | 	ImGui::Text("Verts: %i", ES.verts); | ||||||
|  | 	ImGui::Text("Draw Calls: %i", ES.DC); | ||||||
|  |  | ||||||
|  | 	ImGui::End(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | PerfSampler::PerfSampler(const std::string& name )  | ||||||
|  | : name(name) | ||||||
|  | { | ||||||
|  | 	using namespace std::chrono; | ||||||
|  | 	startTime = high_resolution_clock::now(); | ||||||
|  | 	 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | PerfSampler::~PerfSampler() | ||||||
|  | { | ||||||
|  | 	Stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void PerfSampler::Stop() | ||||||
|  | { | ||||||
|  | 	using namespace std::chrono; | ||||||
|  | 	auto end = high_resolution_clock::now(); | ||||||
|  | 	auto durationInuSeconds =  | ||||||
|  | 		duration_cast<nanoseconds>(end.time_since_epoch()).count() -  | ||||||
|  | 		duration_cast<nanoseconds>(startTime.time_since_epoch()).count(); | ||||||
|  |  | ||||||
|  | 	auto ms = durationInuSeconds * 0.001f; | ||||||
|  |  | ||||||
|  | //	std::cout << "[" << name << "]" <<  "Took: " << durationInuSeconds << " us (" << ms << " ms)" << std::endl; | ||||||
|  | } | ||||||
| @ -1,52 +1,37 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  | #include <string> | ||||||
|  | #include <vector> | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <imgui.h> |  | ||||||
|  |  | ||||||
| struct EngineStatistics { | struct EngineStatistics { | ||||||
| 	float frameTime; | 	float frameTime; | ||||||
| 	uint32_t verts; | 	uint32_t verts; | ||||||
| 	uint32_t DC; | 	uint32_t DC; | ||||||
|  |  | ||||||
| 	long long lastSampleTime; | 	int64_t frames; | ||||||
| 	long long frames; | 	int64_t  FPS; | ||||||
| 	long long  FPS; |  | ||||||
| }; | }; | ||||||
| extern EngineStatistics ES; |  | ||||||
|  |  | ||||||
| inline void PerfomanceSamplerInit(){ | class EngineInstrumentation { | ||||||
|  | public: | ||||||
|  |  | ||||||
| 	ES.frames = 0; | 	//static int64_t lastSampleTime; | ||||||
| 	ES.lastSampleTime = 0; |  | ||||||
| 	ES.lastSampleTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); |  | ||||||
|  |  | ||||||
| } | 	static uint64_t GetPrecisionTime(); | ||||||
|  | 	static void PerfomanceSamplerInit(); | ||||||
|  |  | ||||||
| inline void SamplePerformance(void) { | 	static void Update(); | ||||||
| 	ES.frames++;  | 	static void ShowStats(); | ||||||
| 	ES.DC = 0;  |  | ||||||
| 	ES.verts = 0;  |  | ||||||
| 	unsigned long long  now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();  |  | ||||||
| 	unsigned long long MilliSecondsPast = now - ES.lastSampleTime;  |  | ||||||
| 	if (MilliSecondsPast >= 1000) { |  | ||||||
|  |  | ||||||
| 			ES.frameTime = (float)1000 / ES.frames;  | }; | ||||||
| 			ES.FPS = ES.frames;  |  | ||||||
| 			ES.frames = 0;  |  | ||||||
| 			ES.lastSampleTime = now;  |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | class PerfSampler { | ||||||
|  | public: | ||||||
|  |  | ||||||
|  | 	PerfSampler(const std::string& name); | ||||||
| inline void ShowStats() { | 	~PerfSampler(); | ||||||
| 	ImGui::Begin("Statistics", false, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove); | 	void Stop(); | ||||||
|  | private: | ||||||
| 	ImGui::Text("FPS: %i",			ES.FPS); | 	const std::string& name; | ||||||
| 	ImGui::Text("Frame Time: %f",	ES.frameTime); | 	std::chrono::time_point<std::chrono::high_resolution_clock> startTime; | ||||||
| 	ImGui::Text("Verts: %i",			ES.verts); | }; | ||||||
| 	ImGui::Text("Draw Calls: %i",	ES.DC); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 	ImGui::End(); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -8,8 +8,14 @@ namespace BarinkEngine { | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct TransformComponent { | 	struct TransformComponent { | ||||||
| 		glm::mat4 transform = glm::mat4(1.0f); | 		glm::vec3 Position = glm::vec3(0.0f); | ||||||
|  | 		glm::vec3 Rotation = glm::vec3(0.0f); | ||||||
|  | 		glm::vec3 Scale = glm::vec3(1.0f); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct LightComponent { | ||||||
|  | 		float Strength = 1.0f; | ||||||
|  | 		glm::vec3 Color = glm::vec3(1.0f, 1.0f, 1.0f); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -18,11 +24,15 @@ namespace BarinkEngine { | |||||||
|  |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	struct ScriptComponent { | ||||||
|  | 		std::string file; // TODO : replace with proper properties | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	struct Render3DComponent { | 	struct Render3DComponent { | ||||||
| 		unsigned int VAO = 0; | 		unsigned int VAO = 0; | ||||||
| 		unsigned int IBO = 0; | 		unsigned int IBO = 0; | ||||||
| 		Mesh mesh; | 		Mesh mesh; | ||||||
|  |  | ||||||
| 		// TODO: becomes a material  | 		// TODO: becomes a material  | ||||||
| 		glm::vec3 color; | 		glm::vec3 color; | ||||||
| 		Shader shader; | 		Shader shader; | ||||||
|  | |||||||
| @ -2,13 +2,13 @@ | |||||||
| #include <entt/entt.hpp> | #include <entt/entt.hpp> | ||||||
| class Scene; | class Scene; | ||||||
|  |  | ||||||
|  |  | ||||||
| class Entity { | class Entity { | ||||||
| public: | public: | ||||||
| 	Entity() = default; | 	Entity() = default; | ||||||
| 	Entity(entt::entity e, Scene* scene); | 	Entity(entt::entity e, Scene* scene); | ||||||
| 	Entity(const Entity& other) = default; | 	Entity(const Entity& other) = default; | ||||||
|  |  | ||||||
|  |  | ||||||
| 	template<class T > | 	template<class T > | ||||||
| 	T& AddComponent() { | 	T& AddComponent() { | ||||||
| 		return m_scene->m_registry.emplace<T>(m_entity); | 		return m_scene->m_registry.emplace<T>(m_entity); | ||||||
| @ -19,6 +19,19 @@ public: | |||||||
| 		return m_scene->m_registry.get<T>(m_entity); | 		return m_scene->m_registry.get<T>(m_entity); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	 | ||||||
|  | 	template<class T> | ||||||
|  | 	bool HasComponent() { | ||||||
|  | 		return m_scene->getReg().all_of<T>(m_entity); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	 | ||||||
|  | 	 | ||||||
|  | 	// NOTE: Not Scene context aware!! | ||||||
|  | 	bool operator== (Entity& other) { | ||||||
|  | 		return m_entity == other.m_entity; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	entt::entity m_entity; | 	entt::entity m_entity; | ||||||
| 	Scene* m_scene; | 	Scene* m_scene; | ||||||
|  | |||||||
| @ -3,19 +3,22 @@ | |||||||
| #include "Components.h" | #include "Components.h" | ||||||
| Scene::Scene() | Scene::Scene() | ||||||
| { | { | ||||||
|  | 	//m_registry = entt::basic_registry(); | ||||||
| } | } | ||||||
|  |  | ||||||
| Scene::~Scene() | Scene::~Scene() | ||||||
| {} | {} | ||||||
|  |  | ||||||
| Entity Scene::AddEntity(std::string& name) | Entity Scene::AddEntity(std::string name) | ||||||
| { | { | ||||||
| 	Entity entity = { m_registry.create(), this }; | 	Entity entity = { m_registry.create(), this }; | ||||||
|  |  | ||||||
| 	entity.AddComponent<BarinkEngine::IdentifierComponent>(); | 	auto& ident = entity.AddComponent<BarinkEngine::IdentifierComponent>(); | ||||||
|  | 	ident.name = name; | ||||||
| 	entity.AddComponent<BarinkEngine::TransformComponent>(); | 	entity.AddComponent<BarinkEngine::TransformComponent>(); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	return entity; | 	return entity; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ public: | |||||||
| 	Scene(); | 	Scene(); | ||||||
| 	~Scene(); | 	~Scene(); | ||||||
|  |  | ||||||
| 	Entity AddEntity(std::string& name); | 	Entity AddEntity(std::string name); | ||||||
|  |  | ||||||
| 	entt::registry& getReg() { return m_registry; } | 	entt::registry& getReg() { return m_registry; } | ||||||
|  |  | ||||||
|  | |||||||
| @ -4,7 +4,8 @@ kind "ConsoleApp" | |||||||
| buildmessage "Building editor ..." | buildmessage "Building editor ..." | ||||||
|  |  | ||||||
| links{ | links{ | ||||||
|   "BarinkEngine" |   "BarinkEngine", | ||||||
|  |   "ImGuizmo" | ||||||
| } | } | ||||||
|  |  | ||||||
| includedirs{ | includedirs{ | ||||||
| @ -24,7 +25,9 @@ includedirs{ | |||||||
|   "./../libs/glew/include", |   "./../libs/glew/include", | ||||||
|   "./../libs/glm", |   "./../libs/glm", | ||||||
|   "./../libs/ImGui", |   "./../libs/ImGui", | ||||||
|  |   "./../libs/guizmo", | ||||||
|  |  | ||||||
|  |   "./../libs/entt/src", | ||||||
|  |  | ||||||
|   "./include" |   "./include" | ||||||
|  |  | ||||||
| @ -38,3 +41,4 @@ files { | |||||||
|   "./include/*.h", |   "./include/*.h", | ||||||
|   "./src/*.cpp" |   "./src/*.cpp" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,116 +1,122 @@ | |||||||
| #include "../../BarinkEngine/src/BarinkEngine.h" | #include <glm/gtc/type_ptr.hpp> | ||||||
| #include "../../BarinkEngine/src/Scene/SceneManager.h" | #include <glm/gtc/matrix_transform.hpp> | ||||||
| #include "../../BarinkEngine/src/Scene/SceneNodeTypes.h" |  | ||||||
| #include "../../BarinkEngine/src/AssetManager/ModelImporter.h" |  | ||||||
| #include "../../BarinkEngine/src/Graphics/Framebuffer.h" |  | ||||||
| #include <imgui.h> | #include <imgui.h> | ||||||
|  |  | ||||||
|  | #include "stb_image.h" | ||||||
|  | #include "../../libs/guizmo/ImGuizmo.h" | ||||||
|  |  | ||||||
|  | #include "../../BarinkEngine/src/BarinkEngine.h" | ||||||
|  | #include "../../BarinkEngine/src/AssetManager/ModelImporter.h" | ||||||
|  | #include "../../BarinkEngine/src/Graphics/Memory/Framebuffer.h" | ||||||
|  | #include "../../BarinkEngine/src/PerfCounter.cpp" | ||||||
|  | #include "../../BarinkEngine/src/Scene/Entity.h" | ||||||
|  | #include "Widgets.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Define globals | * Define globals | ||||||
| */ | */ | ||||||
| Shader* shader; |  | ||||||
|  |  | ||||||
| char* code = new char[254]; |  | ||||||
|  |  | ||||||
| const std::string vertexShaderSource = "build/Debug/test.vs"; |  | ||||||
| const std::string fragmentShaderSource = "build/Debug/test.fs"; |  | ||||||
|  |  | ||||||
| BarinkEngine::ModelImporter* MI = new BarinkEngine::ModelImporter(); |  | ||||||
| Framebuffer* framebuffer; | Framebuffer* framebuffer; | ||||||
| Scene* Level1; | Scene Level1; | ||||||
| BarinkEngine::SceneObject* cube; | BarinkEngine::SceneObject* Model; | ||||||
|  | Entity cube; | ||||||
|  |  | ||||||
|  | entt::entity  Selected; | ||||||
| /* | /* | ||||||
| * Runs once at startup | * Runs once at startup | ||||||
| * - USe to initialize the game/sandbox/demo | * - USe to initialize the game/sandbox/demo | ||||||
| */ | */ | ||||||
| void Start() { | void Start() { | ||||||
|     // Build a basic test scene  |     auto io = ImGui::GetIO(); | ||||||
|     // NOTE: This will later be done through an editor  |     io.Fonts->AddFontFromFileTTF("build/Debug/Fonts/Roboto-Regular.ttf", 18); | ||||||
|   |   | ||||||
|     // Create a level and load it as the current level |  | ||||||
|     std::string levelName("Test Level"); |  | ||||||
|     Level1 = SceneManager::CreateScene(levelName); |  | ||||||
|     SceneManager::LoadScene(*Level1); |  | ||||||
|  |  | ||||||
|     shader = new Shader(vertexShaderSource, fragmentShaderSource); |  | ||||||
|  |  | ||||||
|     // Create a cube node |  | ||||||
|  |  | ||||||
|     cube = MI->Import("build/Debug/Models/cube.obj"); |  | ||||||
|     cube->renderable->material = new Material(*shader); |  | ||||||
|     cube->renderable->material->Color = glm::vec3(1.0f, 0.0f, 0.0f); |  | ||||||
|  |  | ||||||
|     // What is in cube now ??     |  | ||||||
|     std::cout << "mesh vertices: " << cube->renderable->mesh->vertices.size() << std::endl; |  | ||||||
|     std::cout << "mesh elements: " << cube->renderable->mesh->elements.size() << std::endl; |  | ||||||
|  |  | ||||||
|     Level1->GetRoot().addChild(*cube); |  | ||||||
|  |  | ||||||
|     memset(code, '\0', 254); |  | ||||||
|     framebuffer = new Framebuffer(); |     framebuffer = new Framebuffer(); | ||||||
|  |  | ||||||
|     std::cout << "Colour attachment id; " << framebuffer->GetColourAttachment() << std::endl; |  | ||||||
|     // TODO: Move to runtime/ Engine  |  | ||||||
|     // NOTE: Submits should later be done through walking the sceneTree |  | ||||||
|  |  | ||||||
|     renderer.Submit(cube->renderable); |     // Create a level and load it as the current level | ||||||
|  |     auto importer = BarinkEngine::ModelImporter(); | ||||||
|  |      | ||||||
|  |     // Create a cube  | ||||||
|  |     Model = importer.Import("build/Debug/Models/Cube.obj"); | ||||||
|  |     cube = Level1.AddEntity("cube"); | ||||||
|  |      | ||||||
|  |     auto& render3DComponent = cube.AddComponent<BarinkEngine::Render3DComponent>(); | ||||||
|  |     render3DComponent.mesh = *(Model->renderable->mesh); | ||||||
|  |  | ||||||
|  |     cube.GetComponent<BarinkEngine::TransformComponent>().Position = glm::vec3(1.0f, 0.0f, 5.0f); | ||||||
|  |      | ||||||
|  |     auto cube2 = Level1.AddEntity("Cube1"); | ||||||
|  |     auto& rendercube2 = cube2.AddComponent<BarinkEngine::Render3DComponent>(); | ||||||
|  |     rendercube2.mesh = *(Model->renderable->mesh); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     // create an ambient light source | ||||||
|  |     auto AmbientLight = Level1.AddEntity("AmbientLight"); | ||||||
|  |     auto light = AmbientLight.AddComponent<BarinkEngine::LightComponent>(); | ||||||
|  |     light.Color = glm::vec3(1.0f); | ||||||
|  |     light.Strength = 1.0f; | ||||||
|  |  | ||||||
|  |     Selected = (entt::entity) -1; | ||||||
|  |  | ||||||
|  |     renderer.Prepare(Level1); | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Runs every frame | * Runs every frame | ||||||
| * - Use to draw Immediate mode graphics (Not meant for HUD's ) | * - Use to draw Immediate mode graphics (Not meant for HUD's ) | ||||||
| */ | */ | ||||||
| void ImmediateGraphicsDraw() | void ImmediateGraphicsDraw() | ||||||
| { | {   ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); | ||||||
|  |  | ||||||
|     ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()); |  | ||||||
|       |       | ||||||
|     // Show a menu bar |     // Show a menu bar | ||||||
|     ImGui::BeginMainMenuBar(); |     ImGui::BeginMainMenuBar(); | ||||||
|  |  | ||||||
|     if (ImGui::BeginMenu("Application")) { |     if (ImGui::BeginMenu("Application")) { | ||||||
|  |  | ||||||
|  |         if (ImGui::MenuItem("Preferences")) { | ||||||
|  |  | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (ImGui::MenuItem("Exit")) { |         if (ImGui::MenuItem("Exit")) { | ||||||
|             // TODO: Exit application |             // TODO: Exit application | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         ImGui::EndMenu(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (ImGui::BeginMenu("Scene")) { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         if (ImGui::MenuItem("Add Entity")) { | ||||||
|  |             Level1.AddEntity("New entity"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|         ImGui::EndMenu(); |         ImGui::EndMenu(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     ImGui::EndMainMenuBar(); |     ImGui::EndMainMenuBar(); | ||||||
|  |  | ||||||
|  |     //ShowStats(); | ||||||
|  |     Viewport(*framebuffer, Level1); | ||||||
|  |     SceneExplorer(Selected, Level1); | ||||||
|  |     Inspector(Selected, Level1 ); | ||||||
|  |  | ||||||
|     // Show internal BarinkEngine stats |     Settings(); | ||||||
|     ShowStats(); |     AssetsFinder(); | ||||||
|  |     Console(); | ||||||
|  |  | ||||||
|     ImGui::Begin("Viewport"); |     ImGui::ShowDemoWindow(); | ||||||
|         ImGui::Image((void*)(intptr_t)framebuffer->GetColourAttachment(), ImVec2{ 800,600 }); |    ImGui::ShowMetricsWindow(); | ||||||
|     ImGui::End(); |  | ||||||
|     |     | ||||||
|     static float Zoom = 90; |  | ||||||
|     static glm::vec3 Position = glm::vec3(0.0f, 0.0f, 0.0f); |  | ||||||
|     static glm::vec3 Rotation = glm::vec3(0.0f, 0.0f, 0.0f); |  | ||||||
|  |  | ||||||
|     ImGui::Begin("Camera"); | } | ||||||
|         ImGui::SliderFloat("Zoom", &Zoom, 10, 190); |  | ||||||
|         ImGui::InputFloat3("Position:", &Position[0]); |  | ||||||
|  |  | ||||||
|         ImGui::InputFloat3("Rotation:", &Rotation[0]); |  | ||||||
|     ImGui::End(); |  | ||||||
|  |  | ||||||
|     ImGui::Begin("Scripting"); |  | ||||||
|         ImGui::Text("Lua Code"); |  | ||||||
|         ImGui::InputTextMultiline("##", code, 255); |  | ||||||
|         bool runCode = ImGui::Button("Run"); |  | ||||||
|     ImGui::End(); |  | ||||||
|  |  | ||||||
|    ImGui::Begin("Scene Explorer"); |  | ||||||
|    ImGui::End(); |  | ||||||
|  |  | ||||||
|  | void Render()  | ||||||
|  | { | ||||||
|  |     renderer.Render( *framebuffer, Level1); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @ -119,11 +125,14 @@ void ImmediateGraphicsDraw() | |||||||
| */ | */ | ||||||
| void Update() | void Update() | ||||||
| { | { | ||||||
|     // glBindFramebuffer(GL_FRAMEBUFFER, framebuffer->GetId()); | } | ||||||
|  |  | ||||||
|     renderer.Render(*framebuffer); | /* | ||||||
|  | * Runs every physics update | ||||||
|  | */ | ||||||
|  | void fixed_update()  | ||||||
|  | { | ||||||
|      |      | ||||||
|     //   glBindFramebuffer(GL_FRAMEBUFFER, 0); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @ -133,6 +142,4 @@ void Update() | |||||||
| void Stop() | void Stop() | ||||||
| { | { | ||||||
|     delete framebuffer; |     delete framebuffer; | ||||||
|     delete MI; |  | ||||||
|     delete shader; |  | ||||||
| } | } | ||||||
							
								
								
									
										135
									
								
								Editor/src/widgets.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								Editor/src/widgets.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,135 @@ | |||||||
|  | #include "widgets.h" | ||||||
|  | #include <iostream> | ||||||
|  | #include "../../BarinkEngine/src/Scene/Components.h" | ||||||
|  | #include "../../BarinkEngine/src/Scene/Entity.h" | ||||||
|  | class Editor; | ||||||
|  |  | ||||||
|  | void ComponentView(const std::string& componentName, voidFunction func) | ||||||
|  | { | ||||||
|  |     ImGuiWindowFlags_ window_flags = ImGuiWindowFlags_None; | ||||||
|  |     ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); | ||||||
|  |     ImGui::BeginChild(componentName.c_str()); | ||||||
|  |  | ||||||
|  |     func(); | ||||||
|  |  | ||||||
|  |     ImGui::EndChild(); | ||||||
|  |     ImGui::PopStyleVar(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Inspector(entt::entity ent , Scene& scene) { | ||||||
|  |     ImGui::Begin("Inspector"); | ||||||
|  |     static float Zoom = 90; | ||||||
|  |     static glm::vec3 Position = glm::vec3(0.0f, 0.0f, 0.0f); | ||||||
|  |     static glm::vec3 Rotation = glm::vec3(0.0f, 0.0f, 0.0f); | ||||||
|  |     if (scene.getReg().valid(ent)) { | ||||||
|  |  | ||||||
|  |         Entity entity = Entity(ent, &scene); | ||||||
|  |  | ||||||
|  |         auto component = entity.GetComponent<BarinkEngine::IdentifierComponent>(); | ||||||
|  |         ImGui::LabelText("## Name:", component.name.c_str() ); | ||||||
|  |        | ||||||
|  |         if (entity.HasComponent<BarinkEngine::TransformComponent>()) { | ||||||
|  |             auto& transform = entity.GetComponent<BarinkEngine::TransformComponent>(); | ||||||
|  |                 ImGui::DragFloat3("Position", glm::value_ptr(transform.Position) , 0.01); | ||||||
|  |                 ImGui::DragFloat3("Rotation", glm::value_ptr(transform.Rotation), 0.01); | ||||||
|  |                 ImGui::DragFloat3("Scale", glm::value_ptr(transform.Scale), 0.01, 0); | ||||||
|  |            | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (entity.HasComponent<BarinkEngine::LightComponent>()) { | ||||||
|  |             auto& light = entity.GetComponent<BarinkEngine::LightComponent>(); | ||||||
|  |             ImGui::DragFloat("Strength", &light.Strength, 0.001f); | ||||||
|  |             ImGui::ColorEdit3("Colour", glm::value_ptr(light.Color)); | ||||||
|  |            | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (entity.HasComponent <BarinkEngine::CameraComponent>()) { | ||||||
|  |             auto& camera = entity.GetComponent<BarinkEngine::CameraComponent>(); | ||||||
|  |             ComponentView("Camera", [] { | ||||||
|  |                 ImGui::SliderFloat("Zoom", &Zoom, 10, 190); | ||||||
|  |                 ImGui::InputFloat3("Position:", &Position[0]); | ||||||
|  |                 ImGui::InputFloat3("Rotation:", &Rotation[0]); | ||||||
|  |                 }); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         if (entity.HasComponent<BarinkEngine::ScriptComponent>()) { | ||||||
|  |             ComponentView("Scripting", [] { | ||||||
|  |                 ImGui::LabelText("##--", "Hello scripting"); | ||||||
|  |                 }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     ImGui::End(); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void SceneExplorer(entt::entity& selected, Scene& scene ) | ||||||
|  | { | ||||||
|  |     ImGui::Begin("Scene Explorer"); | ||||||
|  |  | ||||||
|  |     scene.getReg().each([&](entt::entity enttNumber) { | ||||||
|  |         Entity entity = Entity(enttNumber, &scene); | ||||||
|  |         auto id = entity.GetComponent<BarinkEngine::IdentifierComponent>(); | ||||||
|  |  | ||||||
|  |             if (ImGui::Selectable(id.name.c_str(), enttNumber == selected )) { | ||||||
|  |                 selected = enttNumber; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |     ImGui::End(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Viewport(Framebuffer& framebuffer, Scene& scene) { | ||||||
|  |  | ||||||
|  |     unsigned int viewportWindowFlags = ImGuiWindowFlags_NoTitleBar | ||||||
|  |         | ImGuiWindowFlags_NoDecoration | ||||||
|  |         | ImGuiWindowFlags_NoScrollbar | ||||||
|  |         | ImGuiWindowFlags_NoMove | ||||||
|  |         | ImGuiWindowFlags_NoCollapse; | ||||||
|  |  | ||||||
|  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 0,0 }); | ||||||
|  |     ImGui::Begin("Viewport", false, viewportWindowFlags); | ||||||
|  |     ImGui::Image((void*)(intptr_t)framebuffer.GetColourAttachment(), ImVec2{ (float)800,(float)600 }); | ||||||
|  |  | ||||||
|  |     ImGuizmo::SetDrawlist(); | ||||||
|  |     ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, ImGui::GetWindowWidth(), ImGui::GetWindowHeight()); | ||||||
|  |     ImGuizmo::Enable(true); | ||||||
|  |     auto cam = glm::mat4(1.0f); | ||||||
|  |     auto eye = glm::vec3(0.0f); | ||||||
|  |     auto center = glm::vec3(0.0f); | ||||||
|  |     auto up = glm::vec3(0.0f, 1.0f, 0.0f); | ||||||
|  |     auto view = glm::lookAt(eye, center, up); | ||||||
|  |  | ||||||
|  |     glm::mat4 projection = glm::perspective(glm::radians(90.0f), (800.0f / 600.0f), 0.001f, 100.0f); | ||||||
|  |     auto transformMatrix = glm::mat4(1.0f); | ||||||
|  |  | ||||||
|  |     ImGuizmo::Manipulate(glm::value_ptr(view), glm::value_ptr(projection), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(transformMatrix)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     //ImGuizmo::Manipulate(glm::value_ptr(static_cam), glm::value_ptr(static_projection), ImGuizmo::TRANSLATE, ImGuizmo::WORLD, glm::value_ptr(trans)); | ||||||
|  |     ImGuizmo::ViewManipulate(glm::value_ptr(cam), 8.0f, ImVec2{ 0.0f,0.0f }, ImVec2{ 128.0f,128.0f }, 0x10101010); | ||||||
|  |     ImGui::End(); | ||||||
|  |     ImGui::PopStyleVar(); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Settings() { | ||||||
|  |     ImGui::Begin("Settings"); | ||||||
|  |     ImGui::LabelText("##title-settings", "Fine grain control over your engine... "); | ||||||
|  |     ImGui::End(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void Console() { | ||||||
|  |     ImGui::Begin("Console", false); | ||||||
|  |     ImGui::Dummy(ImVec2{ 128, 128 }); | ||||||
|  |     ImGui::End(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void AssetsFinder() { | ||||||
|  |     ImGui::Begin("Asset-Finder", false); | ||||||
|  |     ImGui::Dummy(ImVec2{ 128, 128 }); | ||||||
|  |     ImGui::End(); | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								Editor/src/widgets.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								Editor/src/widgets.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | #pragma once | ||||||
|  | #include <glm/glm.hpp> | ||||||
|  | #include <imgui.h> | ||||||
|  | #include <string> | ||||||
|  | #include "../../libs/guizmo/ImGuizmo.h" | ||||||
|  | #include "../../BarinkEngine/src/BarinkEngine.h" | ||||||
|  | #include <entt/entt.hpp> | ||||||
|  | #include <entt/entity/fwd.hpp> | ||||||
|  | typedef void ( *voidFunction ) (void); | ||||||
|  |  | ||||||
|  | void ComponentView(const std::string& componentName, voidFunction func); | ||||||
|  |  | ||||||
|  | void Inspector(entt::entity entity, Scene& scene); | ||||||
|  |  | ||||||
|  | void SceneExplorer(entt::entity& selected, Scene& scene); | ||||||
|  |  | ||||||
|  | void Viewport(Framebuffer& framebuffer, Scene& scene); | ||||||
|  |  | ||||||
|  | void Settings(); | ||||||
|  |  | ||||||
|  | void Console(); | ||||||
|  |  | ||||||
|  | void AssetsFinder(); | ||||||
							
								
								
									
										19
									
								
								ImGuizmo/premake5.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ImGuizmo/premake5.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | project "ImGuizmo" | ||||||
|  |   kind "StaticLib" | ||||||
|  |  | ||||||
|  |   includedirs { | ||||||
|  |     "../libs/glfw/include", | ||||||
|  |     "../libs/ImGui", | ||||||
|  |     "../libs/guizmo" | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   files { | ||||||
|  |     "../libs/guizmo/*.cpp", | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   libdirs{ | ||||||
|  |     "../libs/ImGui", | ||||||
|  |     "../libs/glad" | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   include("../ImGui") | ||||||
| @ -7,6 +7,7 @@ | |||||||
| #include "GUI.h" | #include "GUI.h" | ||||||
| #include "Util.h" | #include "Util.h" | ||||||
| #include <entt/entt.hpp> | #include <entt/entt.hpp> | ||||||
|  | #include "../../BarinkEngine/src/PerfCounter.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Define globals | * Define globals | ||||||
| @ -16,43 +17,45 @@ Scene scene; | |||||||
| BarinkEngine::Renderable* renderable; | BarinkEngine::Renderable* renderable; | ||||||
| BarinkEngine::SceneObject* object; | BarinkEngine::SceneObject* object; | ||||||
| Entity cube; | Entity cube; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Runs once at startup  | * Runs once at startup  | ||||||
| * - USe to initialize the game/sandbox/demo | * - USe to initialize the game/sandbox/demo | ||||||
| */ | */ | ||||||
| void Start() { | void Start() { | ||||||
|     |  | ||||||
|     cube  = scene.AddEntity((std::string&)"cube"); |  | ||||||
|     auto& render3DComponent = cube.AddComponent<BarinkEngine::Render3DComponent>(); |  | ||||||
|     auto importer = BarinkEngine::ModelImporter(); |     auto importer = BarinkEngine::ModelImporter(); | ||||||
|  |  | ||||||
|  |     // Load in asset(S) | ||||||
|     object = importer.Import("build/Debug/Models/Cube.obj"); |     object = importer.Import("build/Debug/Models/Cube.obj"); | ||||||
|     renderable = object->renderable; |     renderable = object->renderable; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     // Add Entities to the scene | ||||||
|  |     cube  = scene.AddEntity("cube"); | ||||||
|  |     auto& render3DComponent = cube.AddComponent<BarinkEngine::Render3DComponent>(); | ||||||
|     render3DComponent.mesh = *renderable->mesh; |     render3DComponent.mesh = *renderable->mesh; | ||||||
|     cube.GetComponent<BarinkEngine::TransformComponent>() |     cube.GetComponent<BarinkEngine::TransformComponent>() | ||||||
|         .transform = glm::rotate(glm::mat4(1.0f), 32.0f, glm::vec3(0.5f,1.0f,0.0f)); |         .transform = glm::rotate(glm::mat4(1.0f), 32.0f, glm::vec3(0.5f,1.0f,0.0f)); | ||||||
|  |  | ||||||
|  |  | ||||||
|     // Create a second cube |     // Create a second cube | ||||||
|     |     | ||||||
|     auto cube2 = scene.AddEntity((std::string&)"Cube2"); |     auto cube2 = scene.AddEntity("Cube2"); | ||||||
|     auto& cube2Render = cube2.AddComponent<BarinkEngine::Render3DComponent>(); |     auto& cube2Render = cube2.AddComponent<BarinkEngine::Render3DComponent>(); | ||||||
|     cube2Render.mesh = *renderable->mesh; |     cube2Render.mesh = *renderable->mesh; | ||||||
|     cube2Render.color = glm::vec3(0.0f, 1.0f, 0.0f); |     cube2Render.color = glm::vec3(0.0f, 1.0f, 0.0f); | ||||||
|     auto& cube2Trans = cube2.GetComponent<BarinkEngine::TransformComponent>(); |     auto& cube2Trans = cube2.GetComponent<BarinkEngine::TransformComponent>(); | ||||||
|     cube2Trans.transform = glm::translate( glm::mat4(1.0f), glm::vec3(1.0f,0.0f, 5.0f)); |     cube2Trans.transform = glm::translate( glm::mat4(1.0f), glm::vec3(1.0f,0.0f, 5.0f)); | ||||||
|  |  | ||||||
|  |     // Create a light  | ||||||
|  |     auto AmbientLight = scene.AddEntity("AmbientLight"); | ||||||
|  |     AmbientLight.AddComponent<BarinkEngine::LightComponent>(); | ||||||
|  |  | ||||||
|     renderer.Prepare(scene); |     renderer.Prepare(scene); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
| * Runs every frame | * Runs every frame | ||||||
| * - Use to draw Immediate mode graphics (Not meant for HUD's ) | * - Use to draw Immediate mode graphics (Not meant for HUD's ) | ||||||
| @ -60,19 +63,40 @@ void Start() { | |||||||
| void ImmediateGraphicsDraw()  | void ImmediateGraphicsDraw()  | ||||||
| { | { | ||||||
|     // Show internal BarinkEngine stats |     // Show internal BarinkEngine stats | ||||||
|     ShowStats(); |     EngineInstrumentation::ShowStats(); | ||||||
|  |  | ||||||
|  |     ImGui::Begin("Scene view"); | ||||||
|  |     auto group = scene.getReg().view<BarinkEngine::IdentifierComponent>(); | ||||||
|  |     group.each([](auto entity, BarinkEngine::IdentifierComponent& identifier) { | ||||||
|  |          | ||||||
|  |         ImGui::Text("%s", identifier.name.c_str()); | ||||||
|  |          | ||||||
|  |         }); | ||||||
|  |     ImGui::End(); | ||||||
|  |  | ||||||
|  |     ImGui::ShowMetricsWindow(); | ||||||
|  |  | ||||||
|  |     ImGui::Begin("Settings"); | ||||||
|          |          | ||||||
|     ImGui::Begin("Render edit"); |  | ||||||
|  |  | ||||||
|         auto& a = cube.GetComponent<BarinkEngine::Render3DComponent>(); |         auto& a = cube.GetComponent<BarinkEngine::Render3DComponent>(); | ||||||
|      |      | ||||||
|  |         auto& b = cube.GetComponent<BarinkEngine::TransformComponent>(); | ||||||
|  |  | ||||||
|         ImGui::DragFloat3("Color", &a.color[0], 0.01f, 0.0f, 1.0f); |         ImGui::DragFloat3("Color", &a.color[0], 0.01f, 0.0f, 1.0f); | ||||||
|  |  | ||||||
|  |         ImGui::DragFloat3("Position", &b.transform[3][0], 0.01f, 0.0f, 16.0f); | ||||||
|  |  | ||||||
|  |         auto l = scene.getReg().view<BarinkEngine::LightComponent>(); | ||||||
|  |         l.each([](auto entity, BarinkEngine::LightComponent& light) { | ||||||
|  |             ImGui::Text("Lighting"); | ||||||
|  |             ImGui::SliderFloat("Intensity", &light.Strength, 0.0f, 1.0f); | ||||||
|  |             ImGui::SliderFloat3("l-Color", &light.Color[0], 0.0f, 1.0f); | ||||||
|  |  | ||||||
|  |         }); | ||||||
|  |      | ||||||
|     ImGui::End(); |     ImGui::End(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @ -81,8 +105,11 @@ void ImmediateGraphicsDraw() | |||||||
| */ | */ | ||||||
| void Update() | void Update() | ||||||
| { | { | ||||||
|     renderer.Render(scene); | } | ||||||
|  |  | ||||||
|  | void Render()  | ||||||
|  | { | ||||||
|  |     renderer.Render(scene); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								libs/guizmo
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								libs/guizmo
									
									
									
									
									
										Submodule
									
								
							 Submodule libs/guizmo added at 664cf2d738
									
								
							| @ -6,7 +6,7 @@ workspace "BarinkEngine" | |||||||
| 	architecture "x86_64" | 	architecture "x86_64" | ||||||
|  |  | ||||||
| 	targetdir "./%{prj.name}/build/%{cfg.buildcfg}" | 	targetdir "./%{prj.name}/build/%{cfg.buildcfg}" | ||||||
| 	objdir "./%{prj.name}/%{cfg.buildcfg}/intermediates/" | 	objdir "./%{prj.name}/build/%{cfg.buildcfg}/intermediates/" | ||||||
| 	 | 	 | ||||||
| 	startproject("SandboxApp") | 	startproject("SandboxApp") | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user