From 4cd502bbf9bb9c64d651f26e46d4fa68ce9a491e Mon Sep 17 00:00:00 2001 From: RomchikkF Date: Thu, 7 Dec 2023 23:45:07 +0700 Subject: [PATCH 1/3] init --- engine | 2 +- main.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 96 insertions(+), 31 deletions(-) diff --git a/engine b/engine index 0bc85f8..0870823 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 0bc85f8c8e70056c1efbb378df8dfd64e1391215 +Subproject commit 087082334693f8290a73b76bd0627abec926314b diff --git a/main.cpp b/main.cpp index 2dc44a9..2415cd2 100644 --- a/main.cpp +++ b/main.cpp @@ -1,53 +1,118 @@ +#include + #include "engine.hpp" static int SCR_HEIGHT = 600; static int SCR_WIDTH = 800; -const char *cubeSource = "/cube2.obj"; -const char *catSource = "/cat.obj"; -const char *benchSource = "/bench.obj"; - const char *vertexShaderSource = "/vertex/standart.vshader"; const char *fragmentShaderSource = "/fragment/standart.fshader"; +const char *cubeSource = "/cube.obj"; -Object* initModel(); +class MovingSphere : public Object { + private: + float MIN_VELOCITY = 0.001; + public: + Vec3 velocity; + float bounciness = 1; + float friction = 0.1; + + void Update(float dt) override { + transform->Translate(velocity * dt); + velocity *= pow(friction, dt); + if (length(velocity) < MIN_VELOCITY) { + velocity = Vec3(0, 0, 0); + } + } +}; int main() { auto engine = Engine(SCR_WIDTH, SCR_HEIGHT); - Object* testObj = initModel(); - engine.AddObject<>(testObj); - engine.Run(SCR_WIDTH, SCR_HEIGHT); -} -Object* initModel() { - // build and compile our shader program ------------------------------------ Shader vShader = Shader(VertexShader, vertexShaderSource); Shader fShader = Shader(FragmentShader, fragmentShaderSource); + ShaderProgram *shaderProgram = new ShaderProgram(vShader, fShader); + + Model *cubeModel = Model::loadFromFile(cubeSource); + cubeModel->shader = shaderProgram; + Model *sphereModel = Model::GetSphere(); + sphereModel->shader = shaderProgram; + + auto imagesCube = std::vector(); + imagesCube.push_back("/wall.png"); + imagesCube.push_back("/wallspecular.png"); + Material material = { + 4.f, + Texture(imagesCube), + }; + + auto setUpObj = [=, &engine](Transform transform, auto primitive, Model *model) { + auto obj = new Object(); + obj->renderData = new RenderData(); + auto renderData = obj->renderData; + renderData->model = model; + renderData->material = material; + bindRenderData(renderData); - // init a model - Model * model = Model::loadFromFile(catSource); + obj->transform = new Transform(transform); + obj->collider = new Collider { primitive }; + engine.AddObject<>(obj); + return obj; + }; - auto obj = new Object(); - obj->renderData = new RenderData(); - obj->renderData->model = model; - obj->renderData->model->shader = new ShaderProgram(vShader, fShader); + auto aabb = setUpObj( + Transform(Vec3(-4, 0, -3), Vec3(1.0), 0, Vec3(1)), + AABB { + Vec3{-0.5, -0.5, -0.5}, + Vec3{0.5, 0.5, 0.5}, + }, + cubeModel); - obj->transform = new Transform(glm::vec3(0.f, -3.f, -8.f), glm::vec3(.1f, .1f, .1f), glm::mat4(1.0)); - obj->transform->Rotate(1.67f, glm::vec3(-1.f, 0.f, 0.f)); - auto render_data = obj->renderData; + auto sphere = setUpObj( + Transform(Vec3(0, 0, -3), Vec3(1.0), 0, Vec3(1)), + Sphere { Vec3(0.0), 1.0f }, + sphereModel); - bindRenderData(render_data); + auto mesh = setUpObj( + Transform(Vec3(4.0, 0, -3), Vec3(1.0), 0, Vec3(1)), + sphereModel, + sphereModel); - // Maybe this can be less clunky? - // Perhaps variadic functions? - auto images = std::vector(); - images.push_back("/Cat_diffuse.png"); - images.push_back("/Cat_specular.png"); - obj->renderData->material = { - 4.f, - Texture(images), + auto getSphereObj = [=](Transform transform, Object *target, Vec3 speed) { + auto obj = new MovingSphere(); + obj->renderData = new RenderData(); + auto renderData = obj->renderData; + renderData->model = sphereModel; + renderData->material = material; + bindRenderData(renderData); + + obj->transform = new Transform(transform); + + obj->collider = new Collider{Sphere{ + Vec3(0.0), + 1.0f, + }}; + return obj; }; - return obj; + Object *spheres[3] = { + getSphereObj( + Transform(Vec3(-4, 0, 2.0), Vec3(1.0), 0, Vec3(1)), + aabb, + Vec3(0, 0, -1)), + getSphereObj( + Transform(Vec3(0, 0, 2.0), Vec3(1.0), 0, Vec3(1)), + sphere, + Vec3(0, 0, -1)), + getSphereObj( + Transform(Vec3(4, 0, 2.0), Vec3(1.0), 0, Vec3(1)), + mesh, + Vec3(0, 0, -1)), + }; + engine.AddObject<>(spheres[0]); + engine.AddObject<>(spheres[1]); + engine.AddObject<>(spheres[2]); + + engine.Run(SCR_WIDTH, SCR_HEIGHT); } From 36d631f5a52b8f56ad0e13017c2d7060f96e75d3 Mon Sep 17 00:00:00 2001 From: RomchikkF Date: Fri, 8 Dec 2023 03:25:01 +0700 Subject: [PATCH 2/3] bouncing balls --- main.cpp | 187 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 83 deletions(-) diff --git a/main.cpp b/main.cpp index 2415cd2..44f4b32 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "engine.hpp" @@ -10,23 +11,102 @@ const char *fragmentShaderSource = "/fragment/standart.fshader"; const char *cubeSource = "/cube.obj"; -class MovingSphere : public Object { +class MovingBall : public Object { private: float MIN_VELOCITY = 0.001; public: Vec3 velocity; float bounciness = 1; - float friction = 0.1; + float friction = 0; void Update(float dt) override { transform->Translate(velocity * dt); - velocity *= pow(friction, dt); + // transform->Rotate(length(velocity) * dt / transform->GetScale().x / 2, direction); + velocity *= pow(1 - friction, dt); if (length(velocity) < MIN_VELOCITY) { velocity = Vec3(0, 0, 0); } } + + MovingBall(Vec3 position, ShaderProgram * shaderProgram, + std::string diffuseSource, std::string specularSource = "") { + this->renderData = new RenderData(); + this->renderData->model = Model::GetSphere(); + this->renderData->model->shader = shaderProgram; + + auto images = std::vector(); + images.push_back(diffuseSource); + if (specularSource != "") { + images.push_back(specularSource); + } + this->renderData->material = { + 4.f, + Texture(images), + }; + + bindRenderData(this->renderData); + + this->collider = new Collider{Sphere{ + Vec3(0.0), + 1.0f, + }}; + + transform = new Transform(position, Vec3(1., 1., 1.), Mat4(1.0)); + } +}; + +class GameManager : public Object { + public: + std::vector balls; + float minX = -7, maxX = 7, minZ = -7, maxZ = 7; + + void Update(float dt) override { + for (int i = 0; i < balls.size(); ++i) { + auto ball = balls[i]; + Vec3 pos = ball->transform->GetTranslation(); + if (pos.x < minX) { + ball->transform->Translate((1 + ball->bounciness) * Vec3(minX - pos.x, 0, 0)); + ball->velocity = Vec3(- ball->velocity.x, 0, ball->velocity.z) * ball->bounciness; + } + if (pos.x > maxX) { + ball->transform->Translate((1 + ball->bounciness) * Vec3(maxX - pos.x, 0, 0)); + ball->velocity = Vec3(- ball->velocity.x, 0, ball->velocity.z) * ball->bounciness; + } + if (pos.z < minZ) { + ball->transform->Translate((1 + ball->bounciness) * Vec3(0, 0, minZ - pos.z)); + ball->velocity = Vec3(ball->velocity.x, 0, - ball->velocity.z) * ball->bounciness; + } + if (pos.z > maxZ) { + ball->transform->Translate((1 + ball->bounciness) * Vec3(0, 0, maxZ - pos.z)); + ball->velocity = Vec3(ball->velocity.x, 0, - ball->velocity.z) * ball->bounciness; + } + for (int j = i + 1; j < balls.size(); ++j) { + auto ball2 = balls[j]; + if (ball->collider->Collide(*ball->transform, ball2->collider, *ball2->transform)) { + // collision + Vec3 pos2 = ball2->transform->GetTranslation(); + Vec3 center = (pos + pos2) * 0.5f; // collision point + Vec3 speed = ball->velocity - ball2->velocity; // approach speed of 2 balls + Vec3 v = pos - center; // vector towards center of collision + float dotProduct = speed.x * v.x + speed.z * v.z; + float proj = dotProduct / length(v); // projection of speed vector on collision line + Vec3 impulseChange = normalize(v) * proj * (1 + ball->bounciness * ball2->bounciness); + ball->velocity -= impulseChange * 0.5f; + ball2->velocity += impulseChange * 0.5f; + ball->transform->Translate(v * (ball->transform->GetScale().x / length(v) - 1)); + ball2->transform->Translate(v * (1 - ball2->transform->GetScale().x / length(v))); + } + } + } + } + explicit GameManager(std::vector balls) { + this->balls = balls; + } }; +MovingBall *newBall(Vec3 position, Vec3 velocity, + ShaderProgram *sp, std::string diffuseSource, std::string specularSource); + int main() { auto engine = Engine(SCR_WIDTH, SCR_HEIGHT); @@ -34,85 +114,26 @@ int main() { Shader fShader = Shader(FragmentShader, fragmentShaderSource); ShaderProgram *shaderProgram = new ShaderProgram(vShader, fShader); - Model *cubeModel = Model::loadFromFile(cubeSource); - cubeModel->shader = shaderProgram; - Model *sphereModel = Model::GetSphere(); - sphereModel->shader = shaderProgram; - - auto imagesCube = std::vector(); - imagesCube.push_back("/wall.png"); - imagesCube.push_back("/wallspecular.png"); - Material material = { - 4.f, - Texture(imagesCube), - }; - - auto setUpObj = [=, &engine](Transform transform, auto primitive, Model *model) { - auto obj = new Object(); - obj->renderData = new RenderData(); - auto renderData = obj->renderData; - renderData->model = model; - renderData->material = material; - bindRenderData(renderData); - - obj->transform = new Transform(transform); - obj->collider = new Collider { primitive }; - engine.AddObject<>(obj); - return obj; - }; - - auto aabb = setUpObj( - Transform(Vec3(-4, 0, -3), Vec3(1.0), 0, Vec3(1)), - AABB { - Vec3{-0.5, -0.5, -0.5}, - Vec3{0.5, 0.5, 0.5}, - }, - cubeModel); - - auto sphere = setUpObj( - Transform(Vec3(0, 0, -3), Vec3(1.0), 0, Vec3(1)), - Sphere { Vec3(0.0), 1.0f }, - sphereModel); - - auto mesh = setUpObj( - Transform(Vec3(4.0, 0, -3), Vec3(1.0), 0, Vec3(1)), - sphereModel, - sphereModel); - - auto getSphereObj = [=](Transform transform, Object *target, Vec3 speed) { - auto obj = new MovingSphere(); - obj->renderData = new RenderData(); - auto renderData = obj->renderData; - renderData->model = sphereModel; - renderData->material = material; - bindRenderData(renderData); - - obj->transform = new Transform(transform); - - obj->collider = new Collider{Sphere{ - Vec3(0.0), - 1.0f, - }}; - return obj; - }; - - Object *spheres[3] = { - getSphereObj( - Transform(Vec3(-4, 0, 2.0), Vec3(1.0), 0, Vec3(1)), - aabb, - Vec3(0, 0, -1)), - getSphereObj( - Transform(Vec3(0, 0, 2.0), Vec3(1.0), 0, Vec3(1)), - sphere, - Vec3(0, 0, -1)), - getSphereObj( - Transform(Vec3(4, 0, 2.0), Vec3(1.0), 0, Vec3(1)), - mesh, - Vec3(0, 0, -1)), - }; - engine.AddObject<>(spheres[0]); - engine.AddObject<>(spheres[1]); - engine.AddObject<>(spheres[2]); - + std::vector balls; + int ballsCount = 5; + + for (int i = 0; i < ballsCount; ++i) { + MovingBall *sphere = newBall(Vec3(i * 2 - 5, -12, -i), Vec3(3, 0, 1 + i), + shaderProgram, "/wall.png", "/wallspecular.png"); + balls.push_back(sphere); + engine.AddObject<>(sphere); + } + + GameManager *gameManager = new GameManager(balls); + + engine.AddObject(gameManager); + engine.Run(SCR_WIDTH, SCR_HEIGHT); } + +MovingBall *newBall(Vec3 position, Vec3 velocity, + ShaderProgram *sp, std::string diffuseSource, std::string specularSource) { + MovingBall* ball = new MovingBall(position, sp, diffuseSource, specularSource); + ball->velocity = velocity; + return ball; +} \ No newline at end of file From ebd509edf14a732cf52ea6cc38ea14f3c77f4ea3 Mon Sep 17 00:00:00 2001 From: solloball Date: Mon, 11 Dec 2023 11:46:43 +0700 Subject: [PATCH 3/3] added light to main --- engine | 2 +- main.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/engine b/engine index 0870823..ab5cef7 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 087082334693f8290a73b76bd0627abec926314b +Subproject commit ab5cef765e0f458928c6c3f6d8b09ea06f636786 diff --git a/main.cpp b/main.cpp index 44f4b32..55024dd 100644 --- a/main.cpp +++ b/main.cpp @@ -107,6 +107,8 @@ class GameManager : public Object { MovingBall *newBall(Vec3 position, Vec3 velocity, ShaderProgram *sp, std::string diffuseSource, std::string specularSource); +void initLight(Engine& engine); + int main() { auto engine = Engine(SCR_WIDTH, SCR_HEIGHT); @@ -114,6 +116,8 @@ int main() { Shader fShader = Shader(FragmentShader, fragmentShaderSource); ShaderProgram *shaderProgram = new ShaderProgram(vShader, fShader); + initLight(engine); + std::vector balls; int ballsCount = 5; @@ -136,4 +140,50 @@ MovingBall *newBall(Vec3 position, Vec3 velocity, MovingBall* ball = new MovingBall(position, sp, diffuseSource, specularSource); ball->velocity = velocity; return ball; -} \ No newline at end of file +} + + +void initLight(Engine& engine) { + // init light objects + Object* pointLight1 = new Object(); + pointLight1->light = new PointLight( + Vec3(0.2f, 0.2f, 0.2f), Vec3(0.5f, 0.5f, 0.5f), + Vec3(1.0f, 1.0f, 1.0f), Vec3(-0.2, -0.5, -1.2), + 1, 0.09f, 0.032f); + auto pointLight = std::get(pointLight1->light); + engine.AddObject<>(pointLight1); + + Object* pointLight2 = new Object(); + pointLight2->light = new PointLight( + Vec3(0.2f, 0.2f, 0.2f), Vec3(0.5f, 0.5f, 0.5f), + Vec3(1.0f, 1.0f, 1.0f), Vec3(2.3f, -3.3f, -4.0f), + 1, 0.09f, 0.032f); + pointLight = std::get(pointLight2->light); + engine.AddObject<>(pointLight2); + + Object* pointLight3 = new Object(); + pointLight3->light = new PointLight( + Vec3(0.2f, 0.2f, 0.2f), Vec3(0.5f, 0.5f, 0.5f), + Vec3(1.0f, 1.0f, 1.0f), Vec3(0.0f, 0.0f, -3.0f), + 1, 0.09f, 0.032f); + pointLight = std::get(pointLight3->light); + engine.AddObject<>(pointLight3); + + Object* dirLight = new Object(); + dirLight->light = new DirLight( + Vec3(0.05f, 0.05f, 0.05f), Vec3(0.4f, 0.4f, 0.4f), + Vec3(0.5f, 0.5f, 0.5f), Vec3(-0.2f, -1.0f, -0.3f)); + + auto directionLight = std::get(dirLight->light); + engine.AddObject<>(dirLight); + + Object* spotLight = new Object(); + spotLight->light = new SpotLight( + Vec3(0.0f, 0.0f, 0.0f), Vec3(1.0f, 1.0f, 1.0f), + Vec3(1.0f, 1.0f, 1.0f), Vec3(1.0f, 1.0f, 1.0f), + 1.0f, 0.09f, 0.032f, Vec3(0), + glm::cos(glm::radians(12.5f)), + glm::cos(glm::radians(15.0f))); + auto sptLight = std::get(spotLight->light); + engine.AddObject<>(spotLight); +}