diff --git a/cw_8/grk-cw8.vcxproj b/cw_8/grk-cw8.vcxproj index d712d67..2b6eefc 100644 --- a/cw_8/grk-cw8.vcxproj +++ b/cw_8/grk-cw8.vcxproj @@ -14,6 +14,7 @@ + @@ -25,6 +26,7 @@ + diff --git a/cw_8/grk-cw8.vcxproj.filters b/cw_8/grk-cw8.vcxproj.filters index a93d698..7ae4756 100644 --- a/cw_8/grk-cw8.vcxproj.filters +++ b/cw_8/grk-cw8.vcxproj.filters @@ -51,6 +51,9 @@ Source Files\SOIL + + Source Files + @@ -89,6 +92,9 @@ Source Files + + Source Files + diff --git a/cw_8/shaders/part.frag b/cw_8/shaders/part.frag index e69de29..291ec4c 100644 --- a/cw_8/shaders/part.frag +++ b/cw_8/shaders/part.frag @@ -0,0 +1,12 @@ +#version 430 core +in vec2 TexCoords; +in vec4 ParticleColor; +out vec4 FragColor; + +uniform sampler2D sprite; + +void main() +{ + FragColor = (texture(sprite, TexCoords) * ParticleColor); + FragColor = texture(sprite, TexCoords); +} \ No newline at end of file diff --git a/cw_8/shaders/part.vert b/cw_8/shaders/part.vert index e69de29..8671f1b 100644 --- a/cw_8/shaders/part.vert +++ b/cw_8/shaders/part.vert @@ -0,0 +1,22 @@ +#version 430 core +layout (location = 0) in vec3 vertex; +layout (location = 1) in vec2 texCoords; + +out vec2 TexCoords; +out vec4 ParticleColor; + +uniform mat4 transformation; +uniform vec3 position; +uniform vec4 color; + +uniform vec3 cameraUp; +uniform vec3 cameraSide; + +void main() +{ + float scale = 1.0f; + TexCoords = texCoords; + ParticleColor = color; + vec3 worldspacePos = cameraSide*vertex.x + cameraUp*vertex.y; + gl_Position = transformation * vec4((worldspacePos.xyz * scale) + position, 1.0); +} \ No newline at end of file diff --git a/cw_8/src/Particle.cpp b/cw_8/src/Particle.cpp new file mode 100644 index 0000000..ad06a9a --- /dev/null +++ b/cw_8/src/Particle.cpp @@ -0,0 +1,62 @@ +#include "Particle.h" + +ParticleGenerator::ParticleGenerator() { + this->init(); +} + +void ParticleGenerator::Draw(glm::mat4 modelMatrix, GLuint programParticle, GLuint texture, glm::vec3 cameraDir) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glUseProgram(programParticle); + + for (Particle particle : this->particles) { + + glUniform1i(glGetUniformLocation(programParticle, "sprite"), 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + + glUniformMatrix4fv(glGetUniformLocation(programParticle, "transformation"), 1, GL_FALSE, (float*)&(modelMatrix)); + glUniform3f(glGetUniformLocation(programParticle, "position"), particle.position.x, particle.position.y, particle.position.z); + glUniform4f(glGetUniformLocation(programParticle, "color"), particle.color.x, particle.color.y, particle.color.z, particle.color.w); + + glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f))); + + glUniform3f(glGetUniformLocation(programParticle, "cameraSide"), cameraSide.x, cameraSide.y, cameraSide.z); + glUniform3f(glGetUniformLocation(programParticle, "cameraUp"), 0.f, 1.f, 0.f); + + glBindVertexArray(this->VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } + + glUseProgram(0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_BLEND); +} + +void ParticleGenerator::init() { + unsigned int VBO; + float particle_quad[] = { + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, 0.0f + }; + glGenVertexArrays(1, &this->VAO); + glGenBuffers(1, &VBO); + glBindVertexArray(this->VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(particle_quad), particle_quad, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3*sizeof(float))); + glBindVertexArray(0); + + for (unsigned int i = 0; i < 1; i++) { + this->particles.push_back(Particle()); + } +} diff --git a/cw_8/src/Particle.h b/cw_8/src/Particle.h new file mode 100644 index 0000000..e2b7bd7 --- /dev/null +++ b/cw_8/src/Particle.h @@ -0,0 +1,19 @@ +#include +#include "glm.hpp" +#include "glew.h" + +struct Particle { + glm::vec3 position, velocity; + glm::vec4 color; + float life; +}; + +class ParticleGenerator { + public: + void Draw(glm::mat4 modelMatrix, GLuint programParticle, GLuint texture, glm::vec3 cameraDir); + ParticleGenerator(); + private: + std::vector particles; + GLuint VAO; + void init(); +}; diff --git a/cw_8/src/Texture.cpp b/cw_8/src/Texture.cpp index 2548b13..2e0f7c0 100644 --- a/cw_8/src/Texture.cpp +++ b/cw_8/src/Texture.cpp @@ -15,8 +15,8 @@ GLuint Core::LoadTexture( const char * filepath ) glBindTexture(GL_TEXTURE_2D, id); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); int w, h; unsigned char* image = SOIL_load_image(filepath, &w, &h, 0, SOIL_LOAD_RGBA); diff --git a/cw_8/src/projekt.hpp b/cw_8/src/projekt.hpp index e714c37..46f8577 100644 --- a/cw_8/src/projekt.hpp +++ b/cw_8/src/projekt.hpp @@ -9,6 +9,7 @@ #include "Render_Utils.h" #include "Texture.h" +#include "Particle.h" GLuint program; GLuint programSun; @@ -72,6 +73,8 @@ namespace texture { GLuint station_ao; GLuint station_roughness; GLuint station_metallic; + + GLuint particle_fire; } float aspectRatio = 1.f; @@ -100,15 +103,19 @@ glm::mat4 createCameraMatrix(); void drawObjectSun(Core::RenderContext& context, glm::mat4 modelMatrix); void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint albedo, GLuint ao, GLuint normal, GLuint roughness, GLuint metallic); +ParticleGenerator* Particles; + void init(GLFWwindow* window) { glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glEnable(GL_DEPTH_TEST); + //load shaders here + program = shaderLoader.CreateProgram("shaders/pbr.vert", "shaders/pbr.frag"); programSun = shaderLoader.CreateProgram("shaders/sun.vert", "shaders/sun.frag"); - //programParticle = shaderLoader.CreateProgram("shaders/part.vert", "shaders/part.frag"); + programParticle = shaderLoader.CreateProgram("shaders/part.vert", "shaders/part.frag"); //load models here @@ -120,7 +127,6 @@ void init(GLFWwindow* window) loadModelToContext("./models/station.obj", stationContext); - //load textures here texture::sun = Core::LoadTexture("textures/sun/sun.png"); @@ -166,19 +172,20 @@ void init(GLFWwindow* window) texture::station_roughness = Core::LoadTexture("textures/station/roughness.jpg"); texture::station_ao = Core::LoadTexture("textures/station/ao.jpg"); texture::station_metallic = Core::LoadTexture("textures/station/metallic.jpg"); + + texture::particle_fire = Core::LoadTexture("textures/particles/fire.png"); + + Particles = new ParticleGenerator(); } void renderScene(GLFWwindow* window){ glClearColor(0.0f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(program); - float time = glfwGetTime(); updateDeltaTime(time); - //desired objects go here - drawObjectSun(sunContext, glm::scale(glm::vec3(0.1f)) * glm::eulerAngleY(time/10)); + //drawObjectSun(sunContext, glm::scale(glm::vec3(0.1f)) * glm::eulerAngleY(time/10)); glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f))); glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir)); @@ -207,7 +214,6 @@ void renderScene(GLFWwindow* window){ drawObjectPBR(stationContext, glm::translate(glm::vec3(0.f, 3.f, 0.f)) * glm::scale(glm::vec3(0.1f)) * glm::eulerAngleY(time), texture::station_albedo, texture::station_normal, texture::station_ao, texture::station_roughness, texture::station_metallic); //desired objects end here - glUseProgram(0); glfwSwapBuffers(window); } @@ -233,6 +239,8 @@ void processInput(GLFWwindow* window) void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint albedo, GLuint normal, GLuint ao, GLuint roughness, GLuint metallic) { + glUseProgram(program); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); glm::mat4 transformation = viewProjectionMatrix * modelMatrix; @@ -249,6 +257,8 @@ void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint a Core::SetActiveTexture(metallic, "metallicMap", program, 4); Core::DrawContext(context); + + glUseProgram(0); } void drawObjectSun(Core::RenderContext& context, glm::mat4 modelMatrix) { diff --git a/cw_8/textures/particles/fire.png b/cw_8/textures/particles/fire.png new file mode 100644 index 0000000..1a3ab01 Binary files /dev/null and b/cw_8/textures/particles/fire.png differ