This commit is contained in:
Tomas G.
2026-03-13 08:16:01 +01:00
commit 23bb2d2749
104 changed files with 205490 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#ifndef BOAT_H
#define BOAT_H
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <vector>
#include "Input.h"
#include "Ocean.h"
#include "Terrain.h"
#include <string>
#include <tiny_obj_loader.h> // Include tinyobjloader
class Boat {
public:
Boat();
~Boat();
bool init(const char* modelPath, const char* texturePath); // Pass model and texture paths
void cleanup();
void update(const Input& input, const Ocean& ocean, const Terrain& terrain, float deltaTime);
glm::vec3 getPosition() const { return position; }
glm::quat getRotation() const { return rotation; }
float getSpeed() const { return speed; }
bool hasTerrainCollision() const { return lastCollisionWithTerrain; }
bool canDisembark() const { return lastCollisionAllowsDisembark; }
glm::vec3 getDisembarkPosition() const { return lastCollisionPoint; }
void clearCollisionState();
glm::vec3 getBoundingBoxMin() const { return boundingBoxMin; } // **Getter for boundingBoxMin**
glm::vec3 getBoundingBoxMax() const { return boundingBoxMax; } // **Getter for boundingBoxMax**
// Getters for model data to pass to Renderer
const std::vector<glm::vec3>& getVertices() const { return vertices; }
const std::vector<glm::vec3>& getNormals() const { return normals; }
const std::vector<glm::vec2>& getTexCoords() const { return texCoords; }
const std::string& getTexturePath() const { return boatTexturePath; } // Getter for texture path
const std::vector<tinyobj::material_t>& getMaterials() const { return materials; } // Getter for materials
const std::vector<int>& getMaterialIndices() const { return materialIndices; } // Getter for materials
// New: Getter and Setter for boatScale
float getScale() const { return boatScale; }
void setScale(float scale) { boatScale = scale; }
private:
glm::vec3 position;
glm::quat rotation;
float speed;
float steeringSpeed;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
std::vector<int> materialIndices; // New: Store material indices per vertex
std::vector<tinyobj::material_t> materials; // New: Store materials
void handleInput(const Input& input, const Ocean& ocean, const Terrain& terrain, float deltaTime);
void applyWaveMotion(const Ocean& ocean);
bool collidesWithTerrain(const Terrain& terrain, const Ocean& ocean, const glm::vec3& candidatePosition, glm::vec3* collisionPoint) const;
bool isGradientLowForDisembark(const Terrain& terrain, const glm::vec3& collisionPoint) const;
float getCollisionRadius() const;
bool loadModel(const char* path); // Function to load OBJ model
std::string boatTexturePath; // Store texture path for Renderer to access
glm::vec3 boundingBoxMin;
glm::vec3 boundingBoxMax;
int getGridIndex(int x, int z) const; // Helper function to get 1D index from 2D grid indices
float boatScale;
bool speedUpKeyWasDown;
bool speedDownKeyWasDown;
bool lastCollisionWithTerrain;
bool lastCollisionAllowsDisembark;
glm::vec3 lastCollisionPoint;
};
#endif // BOAT_H

View File

@ -0,0 +1,76 @@
// Camera.h
#ifndef CAMERA_H
#define CAMERA_H
#include <glm/glm.hpp>
#include "Input.h" // Optional Shader class
#include "Terrain.h"
class Camera {
public:
enum class Mode {
BoatOrbit,
Fly,
OnFoot
};
Camera();
~Camera();
void init();
void update(const Input& input, const glm::vec3& boatPosition, const Terrain& terrain, float deltaTime);
void lookAt() const;
void toggleFlyMode();
void startOnFoot(const glm::vec3& worldPosition, const Terrain& terrain);
void setBoatMode();
bool isFlyMode() const { return mode == Mode::Fly; }
bool isBoatMode() const { return mode == Mode::BoatOrbit; }
bool isOnFootMode() const { return mode == Mode::OnFoot; }
const char* getModeName() const;
void setAspectRatio(float ratio) { aspectRatio = ratio; }
glm::vec3 getPosition() const { return position; } // Public getter for position
glm::mat4 getViewMatrix() const; // **Declare getViewMatrix() method**
// New: Camera Rotation Control
void handleMouseInput(const Input& input, float deltaTime);
void rotateYaw(float angle);
void rotatePitch(float angle);
private:
glm::vec3 position;
glm::vec3 target; // Point to look at
glm::vec3 up;
float aspectRatio;
float fov;
float nearPlane;
float farPlane;
// New: Camera Rotation State
float yawAngle=0.0f;
float pitchAngle=0.0f;
float rotationSpeed;
float orbitDistance;
float minOrbitDistance;
float maxOrbitDistance;
float targetHeightOffset;
Mode mode;
float flyMoveSpeed;
float flyVerticalSpeed;
float walkMoveSpeed;
float maxWalkGradient;
float onFootEyeHeight;
glm::vec2 onFootVelocityXZ;
float onFootVerticalVelocity;
bool onFootGrounded;
bool jumpKeyWasDown;
float walkAcceleration;
float walkFriction;
float jumpSpeed;
float gravity;
float slideStartGradient;
float slideAcceleration;
float maxSlideSpeed;
};
#endif // CAMERA_H

View File

@ -0,0 +1,54 @@
// Game.h
#ifndef GAME_H
#define GAME_H
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "Renderer.h"
#include "Input.h"
#include "Ocean.h"
#include "Boat.h"
#include "Camera.h"
#include <cstdio>
#include <iostream>
#include "Terrain.h" // Include Terrain header
#include "VolcanoSim.h"
#include <vector>
class Game {
public:
Game();
~Game();
bool init(int argc, char** argv);
void run();
void cleanup();
private:
Renderer renderer;
std::vector<VolcanoSimulation> volcanoes;
Input input;
Ocean ocean;
Boat boat;
Camera camera;
Terrain terrain; // Add Terrain member
bool flyToggleKeyWasDown;
bool interactKeyWasDown;
float boardBoatCooldown;
static void displayCallback();
static void reshapeCallback(int width, int height);
static void keyboardCallback(unsigned char key, int x, int y);
static void keyboardUpCallback(unsigned char key, int x, int y);
static void specialCallback(int key, int x, int y);
static void specialUpCallback(int key, int x, int y);
static void mouseCallback(int button, int state, int x, int y);
static void motionCallback(int x, int y);
static void passiveMotionCallback(int x, int y);
static void timerCallback(int value);
static void updateGame();
static Game* instance; // Singleton for callbacks to access game instance
};
#endif // GAME_H

View File

@ -0,0 +1,48 @@
// Input.h
#ifndef INPUT_H
#define INPUT_H
#include <set>
class Input {
public:
Input();
~Input();
void init();
void update();
void handleKeyPress(unsigned char key);
void handleKeyRelease(unsigned char key);
void handleSpecialKeyPress(int key);
void handleSpecialKeyRelease(int key);
void handleMouseClick(int button, int state, int x, int y);
void handleMouseMove(int x, int y);
bool isKeyDown(unsigned char key) const;
bool isSpecialKeyDown(int key) const;
// Mouse input methods if needed
// New: Mouse Input Methods
bool isMouseButtonDown(int button) const { return mouseButtonsDown[button]; }
int getMouseX() const { return mouseX; }
int getMouseY() const { return mouseY; }
int getMouseDeltaX() const { return mouseDeltaX; }
int getMouseDeltaY() const { return mouseDeltaY; }
int getMouseWheelDelta() const { return mouseWheelDelta; }
private:
std::set<unsigned char> keysDown;
std::set<int> specialKeysDown;
// Mouse state variables if needed
bool mouseButtonsDown[5]; // Up to 5 mouse buttons (GLUT_LEFT_BUTTON, etc.)
int mouseX, mouseY; // Current mouse position
int lastMouseX, lastMouseY; // Last frame's mouse position
int mouseDeltaX, mouseDeltaY; // Mouse movement delta since last frame
int mouseWheelDelta;
int mouseWheelDeltaPending;
};
#endif // INPUT_H

102
projekt_win/include/Ocean.h Normal file
View File

@ -0,0 +1,102 @@
// Ocean.h
#ifndef OCEAN_H
#define OCEAN_H
#include <glm/glm.hpp>
#include <vector>
#include <GL/glew.h> // Include GLEW for OpenGL types like GLuint
#include "utils.h" // **Include utils.h to use checkGLError**
#include <immintrin.h>
#include <x86intrin.h>
#define ASM_TYPE CLEAR_ASM
#define INTRINSIC 1
#define CLEAR_ASM 2
// Structure to hold parameters for a single Gerstner wave component
struct GerstnerWave {
float amplitude; // Wave amplitude (height)
float wavelength; // Wavelength (distance between crests)
float speed; // Wave speed
glm::vec2 direction; // Wave direction (normalized 2D vector in XZ plane)
float phase; // Phase offset
};
struct SimdSGerstnerWave {
float amplitude; // Wave amplitude (height)
float wavelength; // Wavelength (distance between crests)
float speed; // Wave speed
float dir_x;
float dir_y;
float phase; // Phase offset
float k; // k
float w; // w
};
class Ocean {
public:
Ocean(int gridSize);
~Ocean();
bool init();
void cleanup();
void update(float deltaTime);
glm::vec3 getVertex(int x, int z) const;
float getWaveHeight(float x, float z, float time) const;
glm::vec3 getWaveNormal(float x, float z, float time) const; // Calculate wave normal
float getSeaLevelOffset() const { return seaLevelOffset; }
void setGridSize(int newGridSize); // Setter function
int getGridSize() const { return gridSize; }
float getGridSpacing() const { return gridSpacing; }
GLuint getVAO() const; // Get the Vertex Array Object ID
GLuint getIndexCount() const; // Get the number of indices for rendering
float time;
private:
int gridSize;
float gridSpacing;
std::vector<glm::vec3> vertices; // Store vertices for optimization (optional)
std::vector<GerstnerWave> gerstnerWaves; // Vector to store multiple Gerstner wave components
// Wave parameters (adjustable)
float amplitude;
float wavelength;
float frequency;
glm::vec2 direction; // Wave direction
float phase; // Initial phase
GLuint vertexBufferID; // VBO ID for vertex positions
GLuint normalBufferID; // VBO ID for vertex normals
GLuint texCoordBufferID; // VBO ID for texture coordinates
GLuint indexBufferID; // IBO ID for indices
GLuint vaoID; // VAO ID (Vertex Array Object)
unsigned int indexCount; // Number of indices for rendering
std::vector<float> originalWorldX; // Vector to store original undisplaced World X coordinates
std::vector<float> originalWorldZ; // Vector to store original undisplaced World Z coordinates
float baseAmplitude; // Base (maximum) wave amplitude for periodic modulation
float seaLevelOffset;
void generateGrid();
void createBuffers(); // Create and populate VBOs and IBO
void updateBuffers(const std::vector<glm::vec3>& updatedVertices, const std::vector<glm::vec3>& updatedNormals); // Update VBO data
//void updateVertices(std::vector<glm::vec3> * updatedVertices, std::vector<glm::vec3> * updatedNormals, float time); // Update vertex Y positions based on wave function
void updateVertices(std::vector<glm::vec3> * updatedVertices, std::vector<glm::vec3> * updatedNormals, float * originalWorldX_, float * originalWorldZ_, int _grid_size, float time);
int getGridIndex(int x, int z) const; // Helper function to get 1D index from 2D grid indices
float getGerstnerWaveHeight(const GerstnerWave& wave, float x, float z, float time) const; // Calculate height for a single Gerstner wave
glm::vec3 getGerstnerWaveDisplacement(const GerstnerWave& wave, float x, float z, float time) const; // Calculate horizontal displacement for a Gerstner wave
};
#endif // OCEAN_H

View File

@ -0,0 +1,64 @@
// Renderer.h
#ifndef RENDERER_H
#define RENDERER_H
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "Ocean.h"
#include "Boat.h"
#include "Camera.h"
#include "Shader.h" // Optional Shader class
#include "Terrain.h" // Include Terrain header
#include "VolcanoSim.h"
#include <vector>
#include <string>
#define SHOW_GRID 0
#define SHOW_NORM 0
#define SHOW_BOUDING_BOX 1
class Renderer {
public:
Renderer();
~Renderer();
GLuint oceanTextureID;
GLuint boatTextureID;
GLuint terrainTextureID; // Texture ID for terrain
GLuint heightMapTextureID; // **Add heightMapTextureID**
bool init();
void cleanup();
void renderScene(const Ocean &ocean, const Boat &boat, const Camera &camera, const Terrain &Terrain, const std::vector<VolcanoSimulation>& volcanoes);
void reshape(int width, int height);
void drawOcean(const Ocean& ocean, const Camera& camera); // Camera argument added
GLuint getTerrainTextureID() const { return terrainTextureID; } // Getter for terrain texture ID
private:
// Shader shaderProgram; // Optional shader program
GLuint normalMapTextureID;
Shader oceanShader; // Shader program for ocean
Shader terrainShader; // **Add terrainShader member variable**
Shader lavaParticleShader;
GLuint lavaParticleVAO;
GLuint lavaParticleMeshVBO;
GLuint lavaParticleInstanceVBO;
std::string lastBoatTexturePath = "";
bool loadTexture(const char* filename, GLuint& textureID);
void setupLighting();
void drawBoat(const Boat& boat);
void drawMesh(const std::vector<glm::vec3>& vertices, const std::vector<glm::vec3>& normals, const std::vector<glm::vec2>& texCoords,
const std::vector<int>& materialIndices, const std::vector<tinyobj::material_t>& materials); // Modified drawMesh
void drawMeshVBO(const Ocean& ocean); // **Declare drawMeshVBO**
void drawTerrain(const Terrain& terrain, const Camera& camera, const std::vector<VolcanoSimulation>& volcanoes);
void drawLavaFlowsOnTerrain(const Terrain& terrain, const VolcanoSimulation& volcano);
void drawMeshTerainVBO(const Terrain& terrain);
void drawVolcano(const VolcanoSimulation& volcano, const Camera& camera);
void drawHud(const Boat& boat, const Camera& camera);
void drawText2D(float x, float y, const std::string& text, void* font = GLUT_BITMAP_HELVETICA_18);
};
#endif // RENDERER_H

View File

@ -0,0 +1,39 @@
#ifndef SHADER_H
#define SHADER_H
#include <string>
#include <GL/glew.h> // Include GLEW for OpenGL types
#include <glm/glm.hpp> // **ADD THIS LINE - Include GLM header!**
#include <glm/gtc/type_ptr.hpp>
class Shader {
public:
Shader(); // Constructor
~Shader(); // Destructor
bool loadShader(const char* vertexShaderPath, const char* fragmentShaderPath); // Load and compile shaders from files
bool isLoaded() const { return programID != 0; } // Check if shader program is loaded
void use(); // Use (activate) the shader program
void unuse(); // Unuse (deactivate) the shader program
void cleanup(); // Release shader resources
// Uniform setting functions (add more as needed for different uniform types)
void setInt(const std::string& name, int value) const;
void setFloat(const std::string& name, float value) const;
void setVec3(const std::string& name, const glm::vec3& value) const;
void setMat4(const std::string& name, const glm::mat4& mat) const;
void setMat3(const std::string& name, const glm::mat3& mat) const;
private:
GLuint vertexShaderID; // Vertex shader object ID
GLuint fragmentShaderID; // Fragment shader object ID
GLuint programID; // Shader program ID
bool compileShader(GLuint& shaderID, GLenum shaderType, const char* shaderPath);
bool linkShaderProgram();
};
#endif // SHADER_H

View File

@ -0,0 +1,50 @@
// include/Terrain.h
#ifndef TERRAIN_H
#define TERRAIN_H
#include <glm/glm.hpp>
#include <vector>
#include <GL/glew.h> // Include GLEW for OpenGL types like GLuint
#include "Shader.h"
class Terrain {
public:
Terrain(int gridSize, float gridSpacing);
~Terrain();
bool init(GLuint heightMapTextureID);
void cleanup();
glm::vec3 getVertex(int x, int z) const; // Get vertex position at grid index (x, z)
float sampleHeightWorld(float worldX, float worldZ) const;
float sampleGradientMagnitudeWorld(float worldX, float worldZ) const;
float sampleDirectionalGradientWorld(float worldX, float worldZ, const glm::vec2& directionWorld) const;
bool isInsideBoundsWorld(float worldX, float worldZ) const;
int getGridSize() const { return gridSize; }
float getGridSpacing() const { return gridSpacing; }
GLuint getVAO() const { return vaoID; }
GLuint getIndexCount() const { return indexCount; }
glm::vec3 getNormal(int x, int z) const;
glm::vec3 getHighestPoint() const { return highestPoint; }
std::vector<glm::vec3> getHighestPeaks(int count, float minDistanceWorld) const;
private:
int gridSize;
float gridSpacing;
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texCoords;
GLuint vertexBufferID;
GLuint normalBufferID;
GLuint texCoordBufferID;
GLuint indexBufferID;
GLuint vaoID;
unsigned int indexCount;
glm::vec3 highestPoint;
void generateGrid(GLuint heightMapTextureID); // Generate the initial grid of vertices
void createBuffers(); // Create and populate VBOs and IBO
void updateBuffers(); // Update VBO data (not needed for static terrain in this example, but good to have)
};
#endif // TERRAIN_H

View File

@ -0,0 +1,144 @@
#ifndef VOLCANO_SIM_H
#define VOLCANO_SIM_H
#include <cstddef>
#include <vector>
class Terrain;
class VolcanoSimulation {
public:
struct RenderConfig {
float worldX;
float worldY;
float worldZ;
float coneRadius;
float coneHeight;
float lavaFieldRadius;
float particleSpreadScale;
};
VolcanoSimulation();
~VolcanoSimulation();
bool init(std::size_t particleCount, int gridWidth, int gridHeight, unsigned int seed = 1337u);
void stepScalar(float dt);
void stepSIMD(float dt);
std::size_t getParticleCount() const { return particles.size(); }
const float* getParticlePosX() const { return particles.posX.data(); }
const float* getParticlePosY() const { return particles.posY.data(); }
const float* getParticlePosZ() const { return particles.posZ.data(); }
const float* getParticleTemperature() const { return particles.temperature.data(); }
int getGridWidth() const { return width; }
int getGridHeight() const { return height; }
const float* getLavaHeightGrid() const { return lavaHeight.data(); }
const float* getTemperatureGrid() const { return temperature.data(); }
void setRenderConfig(const RenderConfig& config) { renderConfig = config; }
const RenderConfig& getRenderConfig() const { return renderConfig; }
void setCollisionTerrain(const Terrain& terrain, float waterLevelWorld = 0.0f);
float getAverageLavaHeight() const { return averageLavaHeight; }
float getAverageTemperature() const { return averageTemperature; }
private:
class AlignedFloatArray {
public:
AlignedFloatArray();
~AlignedFloatArray();
AlignedFloatArray(const AlignedFloatArray& other);
AlignedFloatArray& operator=(const AlignedFloatArray& other);
AlignedFloatArray(AlignedFloatArray&& other) noexcept;
AlignedFloatArray& operator=(AlignedFloatArray&& other) noexcept;
bool resize(std::size_t count);
float* data();
const float* data() const;
std::size_t size() const;
private:
float* ptr;
std::size_t count;
};
struct ParticleSoA {
AlignedFloatArray posX;
AlignedFloatArray posY;
AlignedFloatArray posZ;
AlignedFloatArray velX;
AlignedFloatArray velY;
AlignedFloatArray velZ;
AlignedFloatArray life;
AlignedFloatArray temperature;
bool resize(std::size_t count);
std::size_t size() const;
};
ParticleSoA particles;
int width;
int height;
AlignedFloatArray terrainHeight;
AlignedFloatArray lavaHeight;
AlignedFloatArray lavaHeightNext;
AlignedFloatArray temperature;
AlignedFloatArray temperatureNext;
float gravity;
float damping;
float particleCooling;
float lavaViscosity;
float lavaCooling;
float diffusionAlpha;
float ambientTemperature;
float ventTemperature;
float lavaSourceRate;
float windX;
float windZ;
float plumeBuoyancy;
float eruptionClock;
float ventPulseLevel;
RenderConfig renderConfig;
float averageLavaHeight;
float averageTemperature;
int collisionTerrainSize;
float collisionTerrainOriginX;
float collisionTerrainOriginZ;
float collisionTerrainSpacing;
float collisionWaterLevelWorld;
std::vector<float> collisionTerrainHeights;
unsigned int rngState;
std::size_t idx(int x, int y) const;
float random01();
float sampleCollisionTerrainHeightWorld(float worldX, float worldZ) const;
void sampleCollisionTerrainGradientWorld(float worldX, float worldZ, float& dHdX, float& dHdZ) const;
void respawnParticle(std::size_t i);
void initTerrainAndLava();
void injectVentSources(float dt);
void updateParticlesScalar(float dt);
void updateParticlesSIMD(float dt);
void updateLavaFluxScalar(float dt);
void updateLavaFluxSIMD(float dt);
void diffuseHeatScalar(float dt);
void diffuseHeatSIMD(float dt);
void updateStats();
};
void runVolcanoBenchmark();
void runVolcanoReference(int frames = 10);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
#ifndef UTILS_H
#define UTILS_H
#include <GL/glew.h>
#include <iostream>
#include <glm/glm.hpp>
#include <x86intrin.h>
#include <vector>
// Helper function to check for OpenGL errors and print a message
void checkGLError(const char* operation);
float perlinNoise(float x, float y); // Placeholder declaration
void convert_vec3_to_float_array(const std::vector<glm::vec3>& src, float * dst);
void convert_float_array_to_vec3(float * src, std::vector<glm::vec3>& dst);
uint64_t rdtsc();
#endif // UTILS_H