This commit is contained in:
Jakub-Prus 2023-02-13 08:02:41 +01:00
parent b66ffaf1d5
commit 9bff8a1d0d
10 changed files with 471 additions and 19 deletions

View File

@ -23,6 +23,7 @@
<ClCompile Include="src\Texture.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\boids.h" />
<ClInclude Include="src\Camera.h" />
<ClInclude Include="src\ex_9_1.hpp" />
<ClInclude Include="src\objload.h" />

View File

@ -53,21 +53,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\objload.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\Render_Utils.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\Shader_Loader.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\Camera.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\Texture.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="src\SOIL\image_helper.h">
<Filter>Source Files\SOIL</Filter>
</ClInclude>
@ -86,8 +71,26 @@
<ClInclude Include="src\SOIL\image_DXT.h">
<Filter>Source Files\SOIL</Filter>
</ClInclude>
<ClInclude Include="src\Camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\objload.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Shader_Loader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Texture.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Render_Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ex_9_1.hpp">
<Filter>Source Files</Filter>
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\boids.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>

70
cw 9/src/Fish.cpp Normal file
View File

@ -0,0 +1,70 @@
#include "Fish.h"
#include "Texture1.h"
#include "Rectangle.h"
#include "glm.hpp"
#include "glew.h"
#include <vector>
Fish::Fish(const glm::vec3& position, const glm::vec3& velocity, Texture* texture)
: m_position(position), m_velocity(velocity), m_texture(texture), m_bounds() {}
void Fish::Update(const std::vector<Fish>& neighbors, const glm::vec3& target, float dt) {
// W tej funkcji nale¿y zaimplementowaæ algorytm boid.
// neighbors jest wektorem s¹siaduj¹cych ryb.
// target jest pozycj¹ drapie¿nika, dt jest ró¿nic¹ czasu miêdzy aktualnym i poprzednim klatkami.
// Pozycja ryby jest aktualizowana na podstawie algorytmu boid.
glm::vec3 average_position(0.0f, 0.0f, 0.0f);
glm::vec3 average_velocity(0.0f, 0.0f, 0.0f);
int count = 0;
for (const Fish& neighbor : neighbors) {
if (&neighbor == this) {
continue;
}
average_position += neighbor.m_position;
average_velocity += neighbor.m_velocity;
++count;
}
if (count > 0) {
average_position /= count;
average_velocity /= count;
}
glm::vec3 center = m_bounds.m_min + (m_bounds.m_max - m_bounds.m_min) * 0.5f;
glm::vec3 avoid = m_position - center;
m_velocity += (average_position - m_position) * 0.05f +
(average_velocity - m_velocity) * 0.05f +
avoid * 0.05f;
if (target != glm::vec3(0.0f, 0.0f, 0.0f)) {
m_velocity += (target - m_position) * 0.05f;
}
m_velocity = glm::normalize(m_velocity);
m_position += m_velocity * dt;
// Ograniczenie pozycji ryby do prostok¹ta.
m_position.x = glm::clamp(m_position.x, m_bounds.m_min.x, m_bounds.m_max.x);
m_position.y = glm::clamp(m_position.y, m_bounds.m_min.y, m_bounds.m_max.y);
m_position.z = glm::clamp(m_position.z, m_bounds.m_min.z, m_bounds.m_max.z);
}
void Fish::Render() const { // W tej funkcji nale¿y zrenderowaæ teksturê ryby w odpowiedniej pozycji. // Mo¿na to zrobiæ na przyk³ad za pomoc¹ biblioteki OpenGL.
glm::mat4 model(1.0f); model = glm::translate(model, m_position);
GLuint model_location = glGetUniformLocation(m_shader_program, "model"); glUniformMatrix4fv(model_location, 1, GL_FALSE, &model[0][0]);
GLuint texture_location = glGetUniformLocation(m_shader_program, "texture_sampler"); glUniform1i(texture_location, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_texture.m_id);
glBindVertexArray(m_vao); glDrawArrays(GL_TRIANGLES, 0, m_vertex_count); glBindVertexArray(0);
}

21
cw 9/src/Fish.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include "glm.hpp"
#include <vector>
class Texture;
class Fish {
public:
Fish::Fish(const glm::vec3& position, const glm::vec3& velocity, Texture* texture);
void Update(const std::vector<Fish>& neighbors, const glm::vec3& target, float dt);
void Render();
private:
glm::vec3 m_position;
glm::vec3 m_velocity;
Texture* m_texture;
Rectangle m_bounds;
};

13
cw 9/src/Predator.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "glm.hpp"
class Predator {
public:
Predator(const glm::vec3& position);
void Render();
private:
glm::vec3 m_position;
};

13
cw 9/src/Rectangle.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "glm.hpp"
class Rectangle {
public:
Rectangle(const glm::vec3& min = glm::vec3(0), const glm::vec3& max = glm::vec3(1));
bool Contains(const glm::vec3& point) const;
glm::vec3 m_min;
glm::vec3 m_max;
};

14
cw 9/src/Texture1.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "glm.hpp"
class Rectangle {
public:
Rectangle(const glm::vec3& min, const glm::vec3& max);
bool Contains(const glm::vec3& point) const;
private:
glm::vec3 m_min;
glm::vec3 m_max;
};

130
cw 9/src/boids.h Normal file
View File

@ -0,0 +1,130 @@
/*#include <vector>
#include <cmath>
#include <glut.h>
//const int WIDTH = 500;
//const int HEIGHT = 500;
const int DEPTH = 600;
const int NUM_BOIDS = 100;
const float BOID_SPEED = 0.01f;
const float BOID_SIZE = 0.50f;
struct Boid
{
float x, y, z;
float dx, dy, dz;
};
std::vector<Boid> boids;
void init()
{
for (int i = 0; i < NUM_BOIDS; i++)
{
Boid b;
b.x = float(rand()) / RAND_MAX * 2 - 1;
b.y = float(rand()) / RAND_MAX * 2 - 1;
b.z = float(rand()) / RAND_MAX * 2 - 1;
b.dx = float(rand()) / RAND_MAX * BOID_SPEED - BOID_SPEED / 2;
b.dy = float(rand()) / RAND_MAX * BOID_SPEED - BOID_SPEED / 2;
b.dz = float(rand()) / RAND_MAX * BOID_SPEED - BOID_SPEED / 2;
boids.push_back(b);
}
}
void updateBoids()
{
for (int i = 0; i < NUM_BOIDS; i++)
{
Boid& b1 = boids[i];
float avgX = 0;
float avgY = 0;
float avgZ = 0;
int count = 0;
for (int j = 0; j < NUM_BOIDS; j++)
{
if (i == j)
continue;
Boid& b2 = boids[j];
float dx = b2.x - b1.x;
float dy = b2.y - b1.y;
float dz = b2.z - b1.z;
float distance = sqrt(dx * dx + dy * dy + dz * dz);
if (distance < BOID_SIZE)
{
b1.dx -= dx / NUM_BOIDS;
b1.dy -= dy / NUM_BOIDS;
b1.dz -= dz / NUM_BOIDS;
}
avgX += b2.dx;
avgY += b2.dy;
avgZ += b2.dz;
count++;
}
avgX /= count;
avgY /= count;
avgZ /= count;
b1.dx += avgX / NUM_BOIDS;
b1.dy += avgY / NUM_BOIDS;
b1.dz += avgZ / NUM_BOIDS;
b1.x += b1.dx;
b1.y += b1.dy;
b1.z += b1.dz;
if (b1.x < 0 || b1.x > 1)
b1.dx *= -1;
if (b1.y < 0 || b1.y > 1)
b1.dy *= -1;
if (b1.z < 0 || b1.z > 1)
b1.dz *= -1;
}
}
void renderBoids()
{
for (int i = 0; i < NUM_BOIDS; i++)
{
glBegin(GL_POINTS);
glVertex3f(boids[i].x, boids[i].y, boids[i].z);
glEnd();
}
}
/*
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);
updateBoids();
renderBoids();
glutSwapBuffers();
}
void reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, float(width) / height, 1, 100);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("Boids");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
init();
glutMainLoop();
return 0;
}
*/

View File

@ -15,6 +15,19 @@
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <string>
#include <vector>
#include <cmath>
#include <glut.h>
const int DEPTH = 100;
const int NUM_BOIDS = 20;
const float BOID_SIZE = 0.05f;
const float MAX_SPEED = 0.02f;
const float NEIGHBOR_RADIUS = 0.1f;
const float SEPARATION_WEIGHT = 1.0f;
const float ALIGNMENT_WEIGHT = 1.0f;
const float COHESION_WEIGHT = 1.0f;
//const unsigned int SHADOW_WIDTH = 16384, SHADOW_HEIGHT = 16384;
const unsigned int SHADOW_WIDTH = 2048, SHADOW_HEIGHT = 2048;
@ -220,6 +233,8 @@ bool animal_in_aquarium = false;
float lastTime = -1.f;
float deltaTime = 0.f;
void updateDeltaTime(float time) {
if (lastTime < 0) {
lastTime = time;
@ -230,6 +245,136 @@ void updateDeltaTime(float time) {
if (deltaTime > 0.1) deltaTime = 0.1;
lastTime = time;
}
struct Boid
{
float x, y, z;
float vx, vy, vz;
};
std::vector<Boid> boids;
void initBoids()
{
for (int i = 0; i < NUM_BOIDS; i++)
{
Boid b;
//b.x = float(rand()) / RAND_MAX * 2 - 1;
b.x = 12;
b.y = 1;
b.z = 4;
b.vx = ((float)rand() / RAND_MAX) * MAX_SPEED * 2.0f - MAX_SPEED;
b.vy = ((float)rand() / RAND_MAX) * MAX_SPEED * 2.0f - MAX_SPEED;
b.vz = ((float)rand() / RAND_MAX) * MAX_SPEED * 2.0f - MAX_SPEED;
boids.push_back(b);
}
}
void updateBoid(Boid& b) {
float separationX = 0.0f, separationY = 0.0f, separationZ = 0.0f;
float alignmentX = 0.0f, alignmentY = 0.0f, alignmentZ = 0.0f;
float cohesionX = 0.0f, cohesionY = 0.0f, cohesionZ = 0.0f;
int numNeighbors = 0;
for (int i = 0; i < NUM_BOIDS; i++) {
Boid b2 = boids[i];
float dx = b.x - b2.x;
float dy = b.y - b2.y;
float dz = b.z - b2.z;
float dist = sqrt(dx * dx + dy * dy + dz * dz);
if (dist > 0.0f && dist < NEIGHBOR_RADIUS) {
numNeighbors++;
separationX += dx / dist;
separationY += dy / dist;
separationZ += dz / dist;
alignmentX += b2.vx;
alignmentY += b2.vy;
alignmentZ += b2.vz;
cohesionX += b2.x;
cohesionY += b2.y;
cohesionZ += b2.z;
}
}
if (numNeighbors > 0) {
separationX /= (float)numNeighbors;
separationY /= (float)numNeighbors;
separationZ /= (float)numNeighbors;
alignmentX /= (float)numNeighbors;
alignmentY /= (float)numNeighbors;
alignmentZ /= (float)numNeighbors;
cohesionX /= (float)numNeighbors;
cohesionY /= (float)numNeighbors;
cohesionZ /= (float)numNeighbors;
separationX = separationX * SEPARATION_WEIGHT;
separationY = separationY * SEPARATION_WEIGHT;
separationZ = separationZ * SEPARATION_WEIGHT;
alignmentX = alignmentX * ALIGNMENT_WEIGHT;
alignmentY = alignmentY * ALIGNMENT_WEIGHT;
alignmentZ = alignmentZ * ALIGNMENT_WEIGHT;
cohesionX = (cohesionX / (float)numNeighbors - b.x) * COHESION_WEIGHT;
cohesionY = (cohesionY / (float)numNeighbors - b.y) * COHESION_WEIGHT;
cohesionZ = (cohesionZ / (float)numNeighbors - b.z) * COHESION_WEIGHT;
b.vx += separationX + alignmentX + cohesionX;
b.vy += separationY + alignmentY + cohesionY;
b.vz += separationZ + alignmentZ + cohesionZ;
float speed = sqrt(b.vx * b.vx + b.vy * b.vy + b.vz * b.vz);
if (speed > MAX_SPEED) {
b.vx = b.vx / speed * MAX_SPEED;
b.vy = b.vy / speed * MAX_SPEED;
b.vz = b.vz / speed * MAX_SPEED;
}
}
b.x += b.vx;
b.y += b.vy;
b.z += b.vz;
if (b.x < -1.0f) {
b.vx = abs(b.vx);
}
if (b.x > 4.0f) {
b.vx = -abs(b.vx);
}
if (b.y < -1.0f) {
b.vy = abs(b.vy);
}
if (b.y > 4.0f) {
b.vy = -abs(b.vy);
}
if (b.z < -1.0f) {
b.vz = abs(b.vz);
}
if (b.z > 5.0f) {
b.vz = -abs(b.vz);
}
}
/*
void renderBoids()
{
float time = glfwGetTime();
for (int i = 0; i < NUM_BOIDS; i++)
{
float x = boids[i].x;
float y = boids[i].y;
float z = boids[i].z;
drawObjectPBRWithTexture(models::fish2Context,
glm::translate(glm::vec3(3.f, 1.0f, 0.45f))
* glm::rotate(glm::radians(sin(time / 2) * 5.0f), glm::vec3(1.0f, 0.0f, 0.0f))
* glm::eulerAngleY(time - 12) * glm::translate(glm::vec3(1.2f, 0, 0))
* glm::scale(glm::vec3(0.2f)) * glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(0, 1, 0)),
texture::fishBlueTexture,
0.5f, 0.0f, 0);
}
}*/
glm::mat4 createCameraMatrix()
{
glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir,glm::vec3(0.f,1.f,0.f)));
@ -446,8 +591,24 @@ void renderShadowapSun(GLuint depthMapFBO, glm::mat4 lightVP) {
* glm::eulerAngleY(time - 11) * glm::translate(glm::vec3(1.2f, 0, 0))
* glm::scale(glm::vec3(0.2f)) * glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(0, 1, 0))
);
for (int i = 0; i < NUM_BOIDS; i++)
{
float x = boids[i].x;
float y = boids[i].y;
float z = boids[i].z;
drawObjectDepth(models::fish2Context, lightVP,
glm::translate(glm::vec3(x, y, z))
//*glm::rotate(glm::radians(sin(time / 2 + 23) * 5.0f), glm::vec3(1.0f, 0.0f, 0.0f))
//* glm::eulerAngleY(time - 11)* glm::translate(glm::vec3(1.2f, 0, 0))
//* glm::scale(glm::vec3(0.2f))* glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(0, 1, 0))
);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, WIDTH, HEIGHT);
}
@ -682,13 +843,29 @@ void renderScene(GLFWwindow* window)
drawObjectPBRWithTexture(models::aquariumContext, glm::mat4(), texture::aquariumTexture, 0.8f, 0.0f, 5);
drawObjectPBRWithTexture(models::glassWindowContext, glm::mat4(), texture::glassWallTexture, 0.5f, 0.0f, 5);
for (int i = 0; i < NUM_BOIDS; i++)
{
float x = boids[i].x;
float y = boids[i].y;
float z = boids[i].z;
drawObjectPBRWithTexture(models::fish2Context,
glm::translate(glm::vec3(x, y, z)),
//* glm::rotate(glm::radians(sin(time / 2) * 5.0f), glm::vec3(1.0f, 0.0f, 0.0f))
//* glm::eulerAngleY(time - 12) * glm::translate(glm::vec3(1.2f, 0, 0))
//* glm::scale(glm::vec3(0.2f)) * glm::rotate(glm::mat4(1.0f), glm::radians(180.0f), glm::vec3(0, 1, 0)),
texture::fishGreenTexture,
0.5f, 0.0f, 0);
}
for (int i = 0; i < NUM_BOIDS; i++) {
updateBoid(boids[i]);
}
//Terraingen();
//test depth buffer
/*glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programTest);
@ -700,6 +877,8 @@ void renderScene(GLFWwindow* window)
glfwSwapBuffers(window);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
aspectRatio = width / float(height);
@ -985,9 +1164,18 @@ void processInput(GLFWwindow* window)
void renderLoop(GLFWwindow* window) {
while (!glfwWindowShouldClose(window))
{
//glClear(GL_COLOR_BUFFER_BIT);
//updateBoids();
//renderBoids();
//glfwSwapBuffers(window);
processInput(window);
renderScene(window);
glfwPollEvents();
}
}
//}

View File

@ -39,9 +39,8 @@ int main(int argc, char** argv)
glViewport(0, 0, 500, 500);
init(window);
initBoids();
// uruchomienie glownej petli
renderLoop(window);
shutdown(window);