Vivid
Loading...
Searching...
No Matches
instancing.cpp
1#include "Vivid.h"
2#include "common/maths/Vec.h"
3
4const int number_of_sphere = 36;
5float sphere_radius = 25.0f;
6float space_between_spheres = 150.0f;
7
9{
10private:
11 Vivid::Maths::Vec3 lightColor = Vivid::Maths::Vec3(1.0f, 0.5f, 1.0f);
12 glm::vec3 suzannePosition = glm::vec3(0, 50, -200);
13 glm::vec3 lightPosition = glm::vec3(0, 0, 0);
14
15 Vivid::Mesh lightMesh;
16 Ref<Vivid::Shader> lightShader;
17 Ref<Vivid::Entity> suzanne = Vivid::ECS::CreateEntity("Sphere");
18 Ref<Vivid::Entity> light = Vivid::ECS::CreateEntity("Light");
19 Ref<Vivid::ModelComponent> modelComponent1;
20 Ref<Vivid::TransformComponent> sphereTransformComponent = Vivid::ECS::CreateComponent<Vivid::TransformComponent>();
21 Vivid::Mesh* sphere;
22
23 Ref<Vivid::DirectionalLightComponent> directionalLightComponent;
24 Ref<Vivid::Shader> shader;
25
26 std::vector<Vivid::Maths::Vec3> translations;
27
28public:
29 void Setup() override
30 {
31 // Can write custom opengl confs here
32 OPENGL_CONFS
33
34 shader = MakeRef<Vivid::Shader>(
35 "./../assets/shaders/instancing.vertexShader.glsl",
36 "./../assets/shaders/instancing.pixelShader.glsl");
37
38 sphere = new Vivid::Mesh("./../assets/obj/newIcoSphere.obj", number_of_sphere);
39 sphere->BindShader(shader);
40
41 modelComponent1 = Vivid::ECS::CreateComponent<Vivid::ModelComponent>();
42 modelComponent1->AddMesh(sphere);
43 sphereTransformComponent->SetScale(Vivid::Maths::Vec3(sphere_radius));
44
45 directionalLightComponent = Vivid::ECS::CreateComponent<Vivid::DirectionalLightComponent>();
46 directionalLightComponent->SetDirection(Vivid::Maths::Vec3(-0.67f, 0.625f, 0.480f));
47
48 Vivid::ECS::AddComponent(modelComponent1->GetComponentID(), suzanne->GetEntityID());
49 Vivid::ECS::AddComponent(sphereTransformComponent->GetComponentID(), suzanne->GetEntityID());
50
51 Vivid::ECS::AddComponent(directionalLightComponent->GetComponentID(), light->GetEntityID());
52
53 // Initialize the translations
54 for (unsigned int i = 0; i < number_of_sphere; i++)
55 {
56 Vivid::Maths::Vec3 translation;
57
58 // Make a grid of sphere
59 translation.x = (float)(i % 6) * space_between_spheres + 200.0f;
60 translation.y = (float)(i / 6) * space_between_spheres + 200.0f;
61 translation.z = 0.0f;
62
63 translations.push_back(translation);
64 translations[i] = translation;
65 }
66 }
67
68 void Draw() override
69 {
70 sphereTransformComponent->SetScale(Vivid::Maths::Vec3(sphere_radius));
71 for (unsigned int i = 0; i < number_of_sphere; i++)
72 {
73 Vivid::Maths::Vec3 translation;
74
75 // Make a grid of sphere
76 translation.x = (float)(i % 6) * space_between_spheres;
77 translation.y = (float)(i / 6) * space_between_spheres;
78 translation.z = 0.0f;
79
80 translations[i] = translation;
81 }
82
83 Vector<Vivid::DirectionalLightComponent*> directionalLights;
84 Vivid::ECS::GetAllComponents(Vivid::ComponentType::DirectionalLightComponent, directionalLights);
85 Vivid::Maths::Vec3 lightDir = directionalLights[0]->GetDirection();
86
87 sphere->BindShader(shader);
88 shader->SetUniform3f("LightDir", lightDir);
89 shader->SetUniform3f("LightColor", lightColor);
90 for (unsigned int i = 0; i < number_of_sphere; i++)
91 {
92 shader->SetUniform3f(("offsets[" + std::to_string(i) + "]"),
93 translations[i]);
94 }
95
96 // Ray Cast to a sphere
97 // A Better approach would be to use a object based buffer
98 // An object based buffer essentially renders objects with their color to a
99 // hash of it's objectID. Using that we can get the objectID of the selected
100 // pixel and get the object. But since it's just sphere, we can use ray cast
101 // to get the object pretty easily without modifying the renderer by a lot.
102 if (InputHandler::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_LEFT))
103 {
105 OrthoCamera* camera = static_cast<OrthoCamera*>(Application::GetInstance()->GetCamera());
106 mousePos = camera->ScreenToWorldCoords(mousePos.x, mousePos.y);
107 Vivid::Maths::Vec3 hitPos = Vivid::Maths::Vec3(mousePos.x, mousePos.y, 0.0f);
108 std::cout << "Mouse Pos: " << hitPos.x << ", " << hitPos.y << "\n";
109
110 // Simply see if the ray intersects with the sphere by iterating through all the spheres
111 // Better approach would be to use a bounding box to check if the ray intersects with the bounding box
112 for (unsigned int i = 0; i < number_of_sphere; i++)
113 {
114 Vivid::Maths::Vec3 translation = translations[i];
115
116 // x^2 + y^2 + z^2 = r^2 => z = sqrt(r^2 - x^2 - y^2)
117 float z2 = sphere_radius * sphere_radius - (hitPos.x - translation.x) * (hitPos.x - translation.x) - (hitPos.y - translation.y) * (hitPos.y - translation.y);
118 if (z2 >= 0.0f)
119 {
120 shader->SetUniform1f("isSelected[" + std::to_string(i) + "]", 1.0f);
121
122 // x^2 + y^2 + z^2 = r^2 => z = sqrt(r^2 - x^2 - y^2)
123 hitPos.z = sqrt(std::max(0.0f, z2));
124 Vivid::Maths::Vec3 normal = hitPos - translation;
125
126 float mag = sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
127 normal = normal * (1.0f / mag);
128 shader->SetUniform3f("hitNormal", normal);
129 }
130 else
131 {
132 shader->SetUniform1f("isSelected[" + std::to_string(i) + "]", 0.0f);
133 }
134 }
135 }
136 }
137
138 void ImGuiRender() override
139 {
140 ImGui::Begin("Debug");
141 ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
142 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
143 ImGui::SliderFloat("Sphere Radius", &sphere_radius, 0.0f, 200.0f);
144 ImGui::SliderFloat("Space Between Spheres", &space_between_spheres, 0.0f, 500.0f);
145 ImGui::End();
146 }
147};
148
149Application* Vivid::CreateApplication()
150{
152 float rot = 0.0f;
153 float zoom = 1.0f;
154
155 OrthoCamera* camera = new OrthoCamera(pos, rot, zoom, -1000.0f, 1000.0f);
156 Application* app = Application::GetInstance(1920, 1080, "Rendering Assignment", camera);
157
158 app->SetRenderingInterface(new ExampleInterface);
159
160 return app;
161}
162
163int main()
164{
165 return Vivid::main(0, nullptr);
166}
Application class.
Definition: Application.h:19
void Setup() override
Setup function.
Definition: instancing.cpp:29
void ImGuiRender() override
ImGuiRender function.
Definition: instancing.cpp:138
void Draw() override
Draw function.
Definition: instancing.cpp:68
A class for the OrthoCamera's.
Definition: OrthoCamera.h:12
RenderingInterface class.
Contains a Mesh.
Definition: Mesh.h:32
bool IsMouseButtonPressed(int button)
Checks if a mouse button is pressed or not.
Vivid::Maths::Vec2 GetMousePositionOnViewport()
Gets the mouse position on the viewport.
Contains a 2D vector.
Definition: Vec.h:108
Contains a 3D vector.
Definition: Vec.h:51