Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
f07b6fdd62 | |||
aa70421d68 |
10
shaders/shader_particles.frag
Normal file
10
shaders/shader_particles.frag
Normal file
@ -0,0 +1,10 @@
|
||||
#version 330 core
|
||||
|
||||
in float lifeTime;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float normalizedLifeTime = lifeTime / 2;
|
||||
fragColor = vec4( 5.f, normalizedLifeTime, 0.f, normalizedLifeTime);
|
||||
};
|
18
shaders/shader_particles.vert
Normal file
18
shaders/shader_particles.vert
Normal file
@ -0,0 +1,18 @@
|
||||
#version 330 core
|
||||
|
||||
layout ( location = 0 ) in vec3 vertex_position;
|
||||
layout ( location = 4 ) in vec4 position;
|
||||
|
||||
uniform mat4 M_v;
|
||||
uniform mat4 M_p;
|
||||
uniform mat4 transformation;
|
||||
uniform float particleSize;
|
||||
out float lifeTime;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 position_viewspace = M_v * transformation * vec4( position.xyz , 1 );
|
||||
position_viewspace.xy += particleSize * (vertex_position.xy - vec2(0.5f));
|
||||
gl_Position = M_p * position_viewspace;
|
||||
lifeTime = position.w;
|
||||
};
|
128
src/ParticleEmiter.cpp
Normal file
128
src/ParticleEmiter.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "ParticleEmiter.h"
|
||||
#include <cstdlib>
|
||||
|
||||
//ParticleEmitter::ParticleEmitter(GLuint* program)
|
||||
//{
|
||||
// this->program = program;
|
||||
//
|
||||
// this->positionsArr = new float[PARTICLES_COUNT * 4];
|
||||
//
|
||||
// particles.resize(PARTICLES_COUNT);
|
||||
// for (int i = 0; i < PARTICLES_COUNT; ++i)
|
||||
// {
|
||||
// particles[i].position = glm::vec3(0);
|
||||
// particles[i].lifetime = randomFloat(1.0f, 2.0f);
|
||||
// particles[i].radius = 0.01f;
|
||||
// }
|
||||
//
|
||||
// generateBuffers();
|
||||
//}
|
||||
|
||||
ParticleEmitter::ParticleEmitter(GLuint* program, int particleCount, float particleSize)
|
||||
{
|
||||
this->program = program;
|
||||
|
||||
this->positionsArr = new float[particleCount * 4];
|
||||
this->particleSize = particleSize;
|
||||
|
||||
particles.resize(particleCount);
|
||||
for (int i = 0; i < particleCount; ++i)
|
||||
{
|
||||
particles[i].position = glm::vec3(0, 100, 0);
|
||||
particles[i].lifetime = randomFloat(1.0f, 2.0f);
|
||||
particles[i].radius = 0.003f;
|
||||
}
|
||||
|
||||
generateBuffers();
|
||||
}
|
||||
|
||||
void ParticleEmitter::generateBuffers()
|
||||
{
|
||||
glGenBuffers(1, &particleVertexBuffer);
|
||||
|
||||
std::vector< float > vertices;
|
||||
vertices.push_back(0.0f); vertices.push_back(0.0f); vertices.push_back(0.0f);
|
||||
vertices.push_back(1.0f); vertices.push_back(0.0f); vertices.push_back(0.0f);
|
||||
vertices.push_back(0.0f); vertices.push_back(1.0f); vertices.push_back(0.0f);
|
||||
vertices.push_back(1.0f); vertices.push_back(1.0f); vertices.push_back(0.0f);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particleVertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glGenBuffers(1, &particlePositionBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particlePositionBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, particles.size() * 4 * sizeof(float), positionsArr, GL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
void ParticleEmitter::setupUniforms(const glm::mat4 transformation, glm::mat4 cameraMatrix, glm::mat4 perspectiveMatrix)
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(*program, "transformation"), 1, GL_FALSE, (float*)&transformation);
|
||||
glUniformMatrix4fv(glGetUniformLocation(*program, "M_v"), 1, GL_FALSE, (float*)&cameraMatrix);
|
||||
glUniformMatrix4fv(glGetUniformLocation(*program, "M_p"), 1, GL_FALSE, (float*)&perspectiveMatrix);
|
||||
glUniform1f(glGetUniformLocation(*program, "particleSize"), this->particleSize);
|
||||
}
|
||||
|
||||
void ParticleEmitter::update(const float dt, const glm::mat4 transformation, glm::mat4 cameraMatrix, glm::mat4 perspectiveMatrix)
|
||||
{
|
||||
glUseProgram(*program);
|
||||
|
||||
setupUniforms(transformation, cameraMatrix, perspectiveMatrix);
|
||||
|
||||
|
||||
for (int i = 0; i < particles.size(); ++i)
|
||||
{
|
||||
particles[i].lifetime -= dt;
|
||||
particles[i].radius += 0.0002;
|
||||
|
||||
if (particles[i].lifetime <= 0.0f)
|
||||
{
|
||||
particles[i].position = glm::vec3(0);
|
||||
particles[i].lifetime = randomFloat(1.0f, 2.0f);
|
||||
particles[i].radius = 0.003f;
|
||||
}
|
||||
|
||||
float radius = particles[i].radius;
|
||||
particles[i].position -= glm::vec3(randomFloat(-radius, radius), dt / 2, randomFloat(-radius, radius));
|
||||
|
||||
positionsArr[i * 4 + 0] = particles[i].position[0];
|
||||
positionsArr[i * 4 + 1] = particles[i].position[1];
|
||||
positionsArr[i * 4 + 2] = particles[i].position[2];
|
||||
positionsArr[i * 4 + 3] = particles[i].lifetime;
|
||||
}
|
||||
}
|
||||
|
||||
void ParticleEmitter::draw()
|
||||
{
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(4);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particlePositionBuffer);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, particles.size() * 4 * sizeof(float), positionsArr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particleVertexBuffer);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particlePositionBuffer);
|
||||
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glVertexAttribDivisor(4, 1);
|
||||
|
||||
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, particles.size());
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(4);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
float ParticleEmitter::randomFloat(float min, float max) {
|
||||
return (max - min) * ((((float)rand()) / (float)RAND_MAX)) + min;
|
||||
}
|
||||
|
||||
ParticleEmitter::~ParticleEmitter()
|
||||
{
|
||||
glDeleteBuffers(1, &particleVertexBuffer);
|
||||
glDeleteBuffers(1, &particlePositionBuffer);
|
||||
}
|
37
src/ParticleEmiter.h
Normal file
37
src/ParticleEmiter.h
Normal file
@ -0,0 +1,37 @@
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
#include "glm.hpp"
|
||||
#include <vector>
|
||||
|
||||
|
||||
#define PARTICLES_COUNT 0
|
||||
|
||||
class ParticleEmitter
|
||||
{
|
||||
public:
|
||||
ParticleEmitter(GLuint* program);
|
||||
ParticleEmitter(GLuint* program, int particleCount, float particleSize);
|
||||
~ParticleEmitter();
|
||||
|
||||
void update(const float dt, const glm::mat4 transformation, glm::mat4 cameraMatrix, glm::mat4 perspectiveMatrix);
|
||||
void draw();
|
||||
|
||||
private:
|
||||
struct Particle
|
||||
{
|
||||
glm::vec3 position;
|
||||
float lifetime = 0.0f;
|
||||
float radius = 0.0f;
|
||||
};
|
||||
|
||||
float* positionsArr;
|
||||
float particleSize = 0.015f;
|
||||
GLuint* program;
|
||||
GLuint particleVertexBuffer;
|
||||
GLuint particlePositionBuffer;
|
||||
std::vector< Particle > particles;
|
||||
|
||||
float randomFloat(float min, float max);
|
||||
void generateBuffers();
|
||||
void setupUniforms(const glm::mat4 transformation, glm::mat4 cameraMatrix, glm::mat4 perspectiveMatrix);
|
||||
};
|
@ -12,6 +12,7 @@
|
||||
#include "Texture.h"
|
||||
#include "Physics.h"
|
||||
#include "Skybox.h"
|
||||
#include "ParticleEmiter.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
@ -20,11 +21,18 @@ GLuint programColor;
|
||||
GLuint programTexture;
|
||||
GLuint programSkybox;
|
||||
GLuint programSun;
|
||||
GLuint programParticle;
|
||||
GLuint cubemapTexture;
|
||||
GLuint cubemapTexture2;
|
||||
GLuint cubemapTexture3;
|
||||
GLuint cubemapTexture4;
|
||||
GLuint cubemapTexture5;
|
||||
GLuint skyboxVAO, skyboxVBO;
|
||||
|
||||
ParticleEmitter* particleEmitterOrbit;
|
||||
ParticleEmitter* particleEmitterStartShip;
|
||||
ParticleEmitter* particleEmitterStartBooster;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
obj::Model planeModel;
|
||||
@ -62,11 +70,18 @@ GLuint textureMoon;
|
||||
|
||||
Core::RenderContext shipContextOrbit, sphereContextOrbit, stationContextOrbit;
|
||||
|
||||
float acceleration = 0.f;
|
||||
float frustumScale = 1.f;
|
||||
bool loading = false;
|
||||
bool reload = false;
|
||||
bool end = false;
|
||||
float orbitSpeed = 0.003f;
|
||||
const glm::mat4 particleStartShipTranslation = glm::translate(glm::vec3(-2.f, 3.1f, 0.f));
|
||||
const glm::mat4 particleStartBoosterTranslation = glm::translate(glm::vec3(-2.f, -4.5f, 0.f));
|
||||
const glm::vec3 particleOrbitOffset = glm::vec3(2.75f, 0.f, -0.f);
|
||||
const glm::mat4 particleOrbitRotation = glm::rotate(glm::radians(90.0f), glm::vec3(0, 0, 1));
|
||||
const glm::mat4 particleOrbitTranslation = glm::translate(glm::vec3(2.75f, 0.f, -0.f)) * glm::rotate(glm::radians(90.0f), glm::vec3(0, 0, 1));
|
||||
float particleLife = 0.f;
|
||||
|
||||
// skybox
|
||||
std::vector<std::string> faces
|
||||
@ -99,7 +114,27 @@ std::vector<std::string> faces3
|
||||
"textures/skybox/stars4.jpeg",
|
||||
};
|
||||
|
||||
//dokwanie
|
||||
std::vector<std::string> faces4
|
||||
{
|
||||
"textures/skybox/stars3.jpeg",
|
||||
"textures/skybox/stars3.jpeg",
|
||||
"textures/skybox/stars3.jpeg",
|
||||
"textures/skybox/stars3.jpeg",
|
||||
"textures/skybox/stars3.jpeg",
|
||||
"textures/skybox/stars3.jpeg",
|
||||
};
|
||||
|
||||
//rozbicie
|
||||
std::vector<std::string> faces5
|
||||
{
|
||||
"textures/skybox/stars4.jpeg",
|
||||
"textures/skybox/stars4.jpeg",
|
||||
"textures/skybox/stars4.jpeg",
|
||||
"textures/skybox/stars4.jpeg",
|
||||
"textures/skybox/stars4.jpeg",
|
||||
"textures/skybox/stars4.jpeg",
|
||||
};
|
||||
|
||||
// Initalization of physical scene (PhysX)
|
||||
Physics pxScene(9.8 /* gravity (m/s^2) */);
|
||||
@ -275,12 +310,20 @@ void keyboard(unsigned char key, int x, int y)
|
||||
|
||||
case 'w':
|
||||
if (orbitSpeed < 0.02f) {
|
||||
if (!loading) {
|
||||
acceleration += 0.1f;
|
||||
}
|
||||
else if (!end) {
|
||||
orbitSpeed += 0.0001f;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (orbitSpeed > 0.001f) {
|
||||
orbitSpeed -= 0.0001f;
|
||||
particleLife -= 0.01f;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -390,6 +433,8 @@ void drawObjectTexture(Core::RenderContext* context, glm::mat4 modelMatrix, GLui
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
shaderLoader.DeleteProgram(programColor);
|
||||
@ -427,6 +472,8 @@ void renderScene()
|
||||
// Update of camera and perspective matrices
|
||||
cameraMatrix = createCameraMatrix();
|
||||
perspectiveMatrix = Core::createPerspectiveMatrix(0.1f, 1500.f);
|
||||
glm::mat4 shipModelStartMatrix = glm::translate(cameraPos + cameraDir * 4.f + glm::vec3(0, -0.25f, 0)) * glm::rotate(glm::orientedAngle(glm::vec3(0, 0, 1), cameraDir, glm::vec3(0, 1, 0)), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.2)) * glm::translate(glm::vec3(2, 0, 0));
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.1f, 0.3f, 1.0f);
|
||||
@ -435,18 +482,24 @@ void renderScene()
|
||||
|
||||
// update transforms from physics simulation
|
||||
updateTransforms();
|
||||
std::cout << acceleration << std::endl;
|
||||
|
||||
if (acceleration > 1 && acceleration < 20) {
|
||||
boxBodies[0]->setLinearVelocity(PxVec3(0, acceleration, 0));
|
||||
boxBodies[1]->setLinearVelocity(PxVec3(0, acceleration, 0));
|
||||
particleEmitterStartBooster->update(0.01f, shipModelStartMatrix * particleStartBoosterTranslation, cameraMatrix, perspectiveMatrix);
|
||||
particleEmitterStartBooster->draw();
|
||||
|
||||
|
||||
if (time > 2 && time < 7) {
|
||||
boxBodies[0]->setLinearVelocity(PxVec3(0, time * 0.8, 0));
|
||||
boxBodies[1]->setLinearVelocity(PxVec3(0, time * 0.8, 0));
|
||||
}
|
||||
|
||||
if (time > 7 && time < 15) {
|
||||
boxBodies[1]->setLinearVelocity(PxVec3(0, 15, 0));
|
||||
if (acceleration > 20 && acceleration < 40) {
|
||||
boxBodies[1]->setLinearVelocity(PxVec3(0, acceleration, 0));
|
||||
particleEmitterStartShip->update(0.01f, shipModelStartMatrix * particleStartShipTranslation, cameraMatrix, perspectiveMatrix);
|
||||
particleEmitterStartShip->draw();
|
||||
}
|
||||
|
||||
if (time > 15) {
|
||||
if (acceleration > 40) {
|
||||
loading = true;
|
||||
lightDir = glm::normalize(glm::vec3(1.0f, -1.0f, -1.0f));
|
||||
lightPos = glm::vec3(0, 0, -800);
|
||||
@ -462,6 +515,7 @@ void renderScene()
|
||||
|
||||
}
|
||||
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
@ -533,6 +587,7 @@ void renderScene()
|
||||
|
||||
float distance = sqrt((cameraPos.x - stationPos.x)*(cameraPos.x - stationPos.x) + (cameraPos.z - stationPos.z)* (cameraPos.z - stationPos.z));
|
||||
std::cout << "distance: " << distance << std::endl;
|
||||
std::cout << "speed: " << orbitSpeed << std::endl;
|
||||
//std::cout << "cameraPos.x: " << cameraPos.x << "cameraPos.z: " << cameraPos.z <<std::endl;
|
||||
//std::cout << "stationPos.x: " << stationPos.x << "stationPos.z: " << stationPos.z << std::endl;
|
||||
if (distance < 5) {
|
||||
@ -556,6 +611,9 @@ void renderScene()
|
||||
glUniform3f(glGetUniformLocation(programSun, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
drawObject(programSun, sphereContextOrbit, glm::translate(lightPos) * glm::scale(glm::vec3(10.f)), glm::vec3(1.0f, 0.8f, 0.2f));
|
||||
|
||||
particleEmitterOrbit->update(0.01f, shipModelOrbitMatrix * particleOrbitTranslation, cameraMatrix, perspectiveMatrix);
|
||||
particleEmitterOrbit->draw();
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glutSwapBuffers();
|
||||
@ -563,6 +621,9 @@ void renderScene()
|
||||
|
||||
//end
|
||||
else
|
||||
{
|
||||
//rozbicie statku
|
||||
if (orbitSpeed > 0.01)
|
||||
{
|
||||
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.0f - appLoadingTime;
|
||||
|
||||
@ -571,10 +632,25 @@ void renderScene()
|
||||
|
||||
cameraMatrix = createCameraMatrixLoading();
|
||||
perspectiveMatrix = Core::createPerspectiveMatrix(0.1f, 1500.f);
|
||||
Skybox::drawSkybox(programSkybox, cameraMatrix, perspectiveMatrix, cubemapTexture3);
|
||||
Skybox::drawSkybox(programSkybox, cameraMatrix, perspectiveMatrix, cubemapTexture5);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
else
|
||||
//dokowanie
|
||||
{
|
||||
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.0f - appLoadingTime;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.1f, 0.3f, 1.0f);
|
||||
|
||||
cameraMatrix = createCameraMatrixLoading();
|
||||
perspectiveMatrix = Core::createPerspectiveMatrix(0.1f, 1500.f);
|
||||
Skybox::drawSkybox(programSkybox, cameraMatrix, perspectiveMatrix, cubemapTexture4);
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -585,10 +661,17 @@ void init()
|
||||
programColor = shaderLoader.CreateProgram("shaders/shader_color.vert", "shaders/shader_color.frag");
|
||||
programTexture = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag");
|
||||
programSkybox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag");
|
||||
programParticle = shaderLoader.CreateProgram("shaders/shader_particles.vert", "shaders/shader_particles.frag");
|
||||
|
||||
cubemapTexture = Skybox::loadCubemap(faces);
|
||||
cubemapTexture2 = Skybox::loadCubemap(faces2);
|
||||
cubemapTexture3 = Skybox::loadCubemap(faces3);
|
||||
cubemapTexture4 = Skybox::loadCubemap(faces4);
|
||||
cubemapTexture5 = Skybox::loadCubemap(faces5);
|
||||
|
||||
particleEmitterOrbit = new ParticleEmitter(&programParticle, 1000, 0.02f);
|
||||
particleEmitterStartShip = new ParticleEmitter(&programParticle, 1000, 0.02f);
|
||||
particleEmitterStartBooster = new ParticleEmitter(&programParticle, 2000, 0.1f);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user