From 0b24cbc7ae76b3aa9f5cb167c8911074bdd03e5d Mon Sep 17 00:00:00 2001 From: xkamikoo <58092037+xkamikoo@users.noreply.github.com> Date: Fri, 12 Feb 2021 03:43:11 +0100 Subject: [PATCH] Asteroids. TODO: find model with small amount of verticles --- grk-project.vcxproj | 6 +- grk-project.vcxproj.filters | 18 +- shaders/shader_asteroid.frag | 62 +++++++ shaders/shader_asteroid.vert | 55 ++++++ shaders/shader_color.frag | 14 -- shaders/shader_color.vert | 16 -- shaders/shader_normal.frag | 62 +++++++ shaders/shader_normal.vert | 54 ++++++ shaders/shader_sun.frag | 3 +- shaders/shader_tex.frag | 13 +- shaders/shader_tex.vert | 2 + src/main.cpp | 327 +++++++++++++++++++++++------------ src/mesh.h | 47 +++++ src/model.h | 7 + 14 files changed, 530 insertions(+), 156 deletions(-) create mode 100644 shaders/shader_asteroid.frag create mode 100644 shaders/shader_asteroid.vert delete mode 100644 shaders/shader_color.frag delete mode 100644 shaders/shader_color.vert create mode 100644 shaders/shader_normal.frag create mode 100644 shaders/shader_normal.vert diff --git a/grk-project.vcxproj b/grk-project.vcxproj index 5332a2d..8bda9b1 100644 --- a/grk-project.vcxproj +++ b/grk-project.vcxproj @@ -11,12 +11,14 @@ + + - - + + diff --git a/grk-project.vcxproj.filters b/grk-project.vcxproj.filters index 7589c2e..70ea294 100644 --- a/grk-project.vcxproj.filters +++ b/grk-project.vcxproj.filters @@ -18,12 +18,6 @@ - - Shader Files - - - Shader Files - Shader Files @@ -60,6 +54,18 @@ Shader Files + + Shader Files + + + Shader Files + + + Shader Files + + + Shader Files + diff --git a/shaders/shader_asteroid.frag b/shaders/shader_asteroid.frag new file mode 100644 index 0000000..8098f4a --- /dev/null +++ b/shaders/shader_asteroid.frag @@ -0,0 +1,62 @@ +#version 430 core + +layout (location = 0) out vec4 FragColor; +layout (location = 1) out vec4 BrightColor; + +struct PointLight { + vec3 position; + vec3 color; + float intensity; +}; + +#define MAX_POINT_LIGHTS 16 + +uniform vec3 cameraPos; +uniform sampler2D diffuseTexture; +uniform sampler2D normalTexture; +uniform PointLight pointLights[MAX_POINT_LIGHTS]; +uniform int LightsCount; + +in vec3 fragPos; +in vec2 vTexCoord; +in vec3 LightPosTS[MAX_POINT_LIGHTS]; +in vec3 CameraPosTS; +in vec3 FragPosTS; + + + +void main() +{ + vec3 fragColor = vec3(0,0,0); + vec3 texture = texture2D(diffuseTexture, vTexCoord).rgb; + //vec3 texture = vec3(textureColor.x, textureColor.y, textureColor.z); + vec3 ambient = vec3(0.1, 0.1, 0.1) * texture; + + vec3 normal = texture2D(normalTexture, vTexCoord).rgb; + normal = normalize(normal * 2.0 - 1.0); + + vec3 V = normalize(CameraPosTS-FragPosTS); + + for(int i = 0; i < LightsCount; i++) + { + vec3 lightDir = normalize(LightPosTS[i] - FragPosTS); + + + vec3 R = reflect(-lightDir,normal); + + float dist = distance(fragPos, pointLights[i].position); + float distance = (1/dist) * (1/dist); + + float spec = pow(max(0,dot(R,V)),2); + float diff = max(0,dot(normal,normalize(lightDir))); + + vec3 diffuse = pointLights[i].color * diff * distance * pointLights[i].intensity; + vec3 specular = spec * pointLights[i].color * (pointLights[i].intensity/dist); + + + fragColor += texture*diffuse+specular; + } + + BrightColor = vec4(0.0, 0.0, 0.0, 1.0); + FragColor = vec4(fragColor+ambient,1.0); +} diff --git a/shaders/shader_asteroid.vert b/shaders/shader_asteroid.vert new file mode 100644 index 0000000..efe5a64 --- /dev/null +++ b/shaders/shader_asteroid.vert @@ -0,0 +1,55 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec2 vertexTexCoord; +layout(location = 2) in vec3 vertexNormal; +layout (location = 3) in vec3 aTangent; +layout (location = 4) in vec3 aBitangent; +layout (location = 5) in mat4 aInstanceMatrix; + +struct PointLight { + vec3 position; + vec3 color; + float intensity; +}; + +#define MAX_POINT_LIGHTS 16 + +uniform mat4 projection; +uniform mat4 view; +uniform vec3 cameraPos; +uniform PointLight pointLights[MAX_POINT_LIGHTS]; +uniform int LightsCount; + + +out vec3 fragPos; +out vec2 vTexCoord; +out vec3 LightPosTS[MAX_POINT_LIGHTS]; +out vec3 CameraPosTS; +out vec3 FragPosTS; + +void main() +{ + gl_Position = projection * view * aInstanceMatrix * vec4(vertexPosition, 1.0); + + mat3 normalMatrix = transpose(inverse(mat3(aInstanceMatrix))); + + vec3 T = normalize(normalMatrix * aTangent); + vec3 N = normalize(normalMatrix * vertexNormal); + // re-orthogonalize T with respect to N + T = normalize(T - dot(T, N) * N); + // then retrieve perpendicular vector B with the cross product of T and N + vec3 B = cross(N, T); + + mat3 TBN = mat3(T, B, N); + + for(int i=0; i cube; std::shared_ptr sphere; @@ -68,16 +69,17 @@ std::shared_ptr asteroid; //std::vector corvetteMeshes; std::shared_ptr crewmate; + +//cameraPos float cameraAngle = 0; glm::vec3 cameraPos = glm::vec3(-6, 0, 0); glm::vec3 cameraDir; glm::vec3 cameraSide; - - glm::mat4 cameraMatrix, perspectiveMatrix; glm::vec3 sunPos = glm::vec3(10.0f, 0.0f, -5.0f); glm::vec3 sunPos2 = glm::vec3(25.0f, -1.0f, 10.0f); + //particlepart struct Particle { glm::vec3 pos, speed; @@ -90,6 +92,16 @@ struct Particle { return this->cameradistance > that.cameradistance; } }; + +struct Object +{ + glm::mat4 modelM; + glm::mat4 invModelM; + std::shared_ptr modelParent; + GLuint textureID; + GLuint shaderID; + glm::vec3 color; +}; const int MaxParticles = 1000; Particle ParticlesContainer[MaxParticles]; @@ -138,8 +150,9 @@ std::vector faces "skybox/back.jpg" }; - +std::vector objects; std::vector lights; +std::vector asteroids; void keyboard(unsigned char key, int x, int y) { @@ -150,7 +163,7 @@ void keyboard(unsigned char key, int x, int y) case 'q': { cameraAngle -= angleSpeed; - lights[3].intensity = 0.005; + lights[3].intensity = 0.05; engineLightTimer = 0; break; } @@ -158,7 +171,7 @@ void keyboard(unsigned char key, int x, int y) case 'e': { cameraAngle += angleSpeed; - lights[2].intensity = 0.005; + lights[2].intensity = 0.05; engineLightTimer = 0; break; } @@ -166,8 +179,8 @@ void keyboard(unsigned char key, int x, int y) case 'w': { cameraPos += cameraDir * moveSpeed; - lights[2].intensity = 0.005; - lights[3].intensity = 0.005; + lights[2].intensity = 0.05; + lights[3].intensity = 0.05; engineLightTimer = 0; break; } @@ -220,31 +233,11 @@ glm::mat4 createCameraMatrix() } float frustumScale = 1.f; - - -void drawObject(GLuint program, Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color) -{ - glUseProgram(program); - - glUniform3f(glGetUniformLocation(program, "objectColor"), color.x, color.y, color.z); - - glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; - - - glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); - glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); - - Core::DrawContext(context); - glUseProgram(0); -} - //funkcja rysujaca modele za pomoca assimpa -void drawFromAssimpModel(GLuint program, std::shared_ptr model, glm::mat4 modelMatrix, glm::vec3 color) +void drawFromAssimpModel(GLuint program, std::shared_ptr model, glm::mat4 modelMatrix) { glUseProgram(program); - glUniform3f(glGetUniformLocation(program, "objectColor"), color.x, color.y, color.z); - glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); @@ -255,14 +248,13 @@ void drawFromAssimpModel(GLuint program, std::shared_ptr model, glm::mat4 glUseProgram(0); } -void drawFromAssimpTexture(GLuint program, std::shared_ptr model, glm::mat4 modelMatrix, glm::vec3 color, GLuint texID) +void drawFromAssimpTexture(GLuint program, std::shared_ptr model, glm::mat4 modelMatrix, GLuint texID) { glUseProgram(program); glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); - glUniform3f(glGetUniformLocation(program, "colorTex"), color.x, color.y, color.z); glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); Core::SetActiveTexture(texID, "diffuseTexture", program, 0); @@ -271,6 +263,31 @@ void drawFromAssimpTexture(GLuint program, std::shared_ptr model, glm::ma glUseProgram(0); } +void drawObject(Object & obj) +{ + glUseProgram(obj.shaderID); + + glm::mat4 transformation = perspectiveMatrix * cameraMatrix * obj.modelM; + + glUniformMatrix4fv(glGetUniformLocation(obj.shaderID, "modelMatrix"), 1, GL_FALSE, (float*)&obj.modelM); + glUniformMatrix4fv(glGetUniformLocation(obj.shaderID, "transformation"), 1, GL_FALSE, (float*)&transformation); + + glUniform3f(glGetUniformLocation(obj.shaderID, "objectColor"), obj.color.r, obj.color.g, obj.color.b); + if (obj.textureID != -1) + Core::SetActiveTexture(obj.textureID, "diffuseTexture", obj.shaderID, 0); + + obj.modelParent->Draw(obj.shaderID); + glUseProgram(0); +} + +void drawAsteroids() +{ + glUseProgram(programAsteroid); + glUniformMatrix4fv(glGetUniformLocation(programAsteroid, "projection"), 1, GL_FALSE, (float*)&perspectiveMatrix); + glUniformMatrix4fv(glGetUniformLocation(programAsteroid, "view"), 1, GL_FALSE, (float*)&cameraMatrix); + asteroid->DrawInstances(programAsteroid, asteroidAmount); +} + //Skybox unsigned int loadCubemap(std::vector faces) { @@ -309,14 +326,11 @@ void drawSkybox(GLuint program, std::shared_ptr cubeModel, GLuint texID) glDepthFunc(GL_LEQUAL); glm::mat4 transformation = perspectiveMatrix * glm::mat4(glm::mat3(cameraMatrix)); glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); - //glDepthMask(GL_FALSE); - //Core::SetActiveTexture(texID, "skybox", program, 0); glUniform1i(glGetUniformLocation(program, "skybox"), 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, texID); cubeModel->Draw(program); glDepthFunc(GL_LESS); - //glDepthMask(GL_TRUE); glUseProgram(0); } @@ -379,19 +393,31 @@ void drawParticles(int ParticlesCount, glm::mat4 &transformation) glDisableVertexAttribArray(2); } -//Textures -void drawObjectTexture(GLuint program, Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 texture, GLuint texID) +void drawBloom() { - glUseProgram(program); - glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; - glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); - glUniform3f(glGetUniformLocation(program, "colorTex"), texture.x, texture.y, texture.z); - glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glBindFramebuffer(GL_FRAMEBUFFER, 0); - Core::SetActiveTexture(texID, "diffuseTexture", program, 0); + bool horizontal = true, first_iteration = true; + unsigned int amount = 10; + glUseProgram(programBlur); + for (unsigned int i = 0; i < amount; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, pingpongFBO[horizontal]); + glUniform1i(glGetUniformLocation(programBlur, "horizontal"), horizontal); + glBindTexture(GL_TEXTURE_2D, first_iteration ? colorBuffers[1] : pingpongColorbuffers[!horizontal]); + renderQuad(); + horizontal = !horizontal; + if (first_iteration) + first_iteration = false; + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); - Core::DrawContext(context); - glUseProgram(0); + glUseProgram(programBloom); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, colorBuffers[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, pingpongColorbuffers[!horizontal]); + renderQuad(); } //funkcja rysujaca planety (bez obracania wokol wlasnej osi bo ksiezyce sie psuja) @@ -430,15 +456,6 @@ void renderScene() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //ustalanie pozycji slonc (lightPos) - glm::mat4 sunModelMatrix = glm::mat4(1.0f); - sunModelMatrix = glm::translate(sunModelMatrix, sunPos); - sunModelMatrix = glm::scale(sunModelMatrix, glm::vec3(3.0f, 3.0f, 3.0f)); - - glm::mat4 sunModelMatrix2 = glm::mat4(1.0f); - sunModelMatrix2 = glm::translate(sunModelMatrix2, sunPos2); - - glm::mat4 earth = drawPlanet(time / 5.0f, sunPos*glm::vec3(1.5f, 1, 1), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(-10.5f, 0.0f, -10.5f), glm::vec3(0.5f, 0.5f, 0.5f)); glm::mat4 moon = drawMoon(earth, time / 2.0f, glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0, 1, 1), glm::vec3(1.5f, 1.0f, 1.0f), glm::vec3(0.3f, 0.3f, 0.3f)); earth = glm::rotate(earth, time / 3.0f, glm::vec3(0.0f, 0.0f, 1.0f)); @@ -449,12 +466,7 @@ void renderScene() glm::mat4 crewmateModelMatrix = glm::translate(glm::vec3(0, 1, 1)) * glm::rotate(time / 2, glm::vec3(1, 0, 1)) * glm::scale(glm::vec3(0.01)); glm::mat4 shipModelMatrix = glm::translate(cameraPos + cameraDir * 0.7f + glm::vec3(0, -0.25f, 0)) * glm::rotate(-cameraAngle + glm::radians(90.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.0001f)); - glm::mat4 testModelMatrix = glm::translate(glm::vec3(1, 0, 0)); - - glUseProgram(programTex); - - lights[0].position = sunPos; - lights[1].position = sunPos2; + glm::mat4 testModelMatrix = glm::translate(glm::vec3(1, 0, 0)) * glm::scale(glm::vec3(0.5f)); glm::mat4 engineLeft = glm::translate(shipModelMatrix, glm::vec3(450, 0, -1500)); lights[2].position = glm::vec3(engineLeft[3][0], engineLeft[3][1], engineLeft[3][2]); @@ -462,6 +474,7 @@ void renderScene() glm::mat4 engineRight = glm::translate(shipModelMatrix, glm::vec3(-450, 0, -1500)); lights[3].position = glm::vec3(engineRight[3][0], engineRight[3][1], engineRight[3][2]); + glUseProgram(programTex); glUniform1i(glGetUniformLocation(programTex,"LightsCount"), lights.size()); for (int i = 0; i < lights.size(); i++) @@ -476,22 +489,54 @@ void renderScene() glUniform3f(glGetUniformLocation(programTex, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); - drawFromAssimpModel(programTex, corvette, shipModelMatrix, glm::vec3(1)); - drawFromAssimpModel(programTex, crewmate, crewmateModelMatrix, glm::vec3(1)); - - drawFromAssimpModel(programTex, asteroid, testModelMatrix, glm::vec3(1)); + drawFromAssimpModel(programTex, crewmate, crewmateModelMatrix); //rysowanie Ziemi z ksiezycem - drawFromAssimpTexture(programTex, sphere, earth, glm::vec3(0.8f, 0.8f, 0.8f), earthTexture); - drawFromAssimpTexture(programTex, sphere, moon, glm::vec3(0.9f, 1.0f, 0.9f), moonTexture); - drawFromAssimpTexture(programTex, sphere, planet1, glm::vec3(0.4f, 0.2f, 0.9f), moonTexture); + drawFromAssimpTexture(programTex, sphere, earth, earthTexture); + drawFromAssimpTexture(programTex, sphere, moon, moonTexture); + drawFromAssimpTexture(programTex, sphere, planet1, moonTexture); + + glUseProgram(programNormal); + + glUniform1i(glGetUniformLocation(programNormal, "LightsCount"), lights.size()); + for (int i = 0; i < lights.size(); i++) + { + std::string col = "pointLights[" + std::to_string(i) + "].color"; + std::string pos = "pointLights[" + std::to_string(i) + "].position"; + std::string ins = "pointLights[" + std::to_string(i) + "].intensity"; + glUniform3f(glGetUniformLocation(programNormal, col.c_str()), lights[i].color.x, lights[i].color.y, lights[i].color.z); + glUniform3f(glGetUniformLocation(programNormal, pos.c_str()), lights[i].position.x, lights[i].position.y, lights[i].position.z); + glUniform1f(glGetUniformLocation(programNormal, ins.c_str()), lights[i].intensity); + } + + glUniform3f(glGetUniformLocation(programNormal, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + + drawFromAssimpModel(programNormal, asteroid, testModelMatrix); + drawFromAssimpModel(programNormal, corvette, shipModelMatrix); glUseProgram(programSun); glUniform3f(glGetUniformLocation(programSun, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); - drawFromAssimpTexture(programSun, sphere, sunModelMatrix, glm::vec3(3.5f, 3.8f, 3.8f), sunTexture); - drawFromAssimpTexture(programSun, sphere, sunModelMatrix2, glm::vec3(0.9f, 0.9f, 2.0f), sunTexture); + for (Object & obj : objects) + drawObject(obj); + + //asteroidpart + glUseProgram(programAsteroid); + glUniform1i(glGetUniformLocation(programAsteroid, "LightsCount"), lights.size()); + for (int i = 0; i < lights.size(); i++) + { + std::string col = "pointLights[" + std::to_string(i) + "].color"; + std::string pos = "pointLights[" + std::to_string(i) + "].position"; + std::string ins = "pointLights[" + std::to_string(i) + "].intensity"; + glUniform3f(glGetUniformLocation(programAsteroid, col.c_str()), lights[i].color.x, lights[i].color.y, lights[i].color.z); + glUniform3f(glGetUniformLocation(programAsteroid, pos.c_str()), lights[i].position.x, lights[i].position.y, lights[i].position.z); + glUniform1f(glGetUniformLocation(programAsteroid, ins.c_str()), lights[i].intensity); + } + + glUniform3f(glGetUniformLocation(programAsteroid, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + drawAsteroids(); + //particlepart glUseProgram(programParticle); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -504,7 +549,6 @@ void renderScene() int newparticles = 0; - if (engineLightTimer < 30) { engineLightTimer++; @@ -599,36 +643,73 @@ void renderScene() SortParticles(); drawParticles(ParticlesCount, transformation); + drawSkybox(programSkybox, cube, skyboxTexture); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - bool horizontal = true, first_iteration = true; - unsigned int amount = 10; - glUseProgram(programBlur); - for (unsigned int i = 0; i < amount; i++) - { - glBindFramebuffer(GL_FRAMEBUFFER, pingpongFBO[horizontal]); - glUniform1i(glGetUniformLocation(programBlur, "horizontal"), horizontal); - glBindTexture(GL_TEXTURE_2D, first_iteration ? colorBuffers[1] : pingpongColorbuffers[!horizontal]); - renderQuad(); - horizontal = !horizontal; - if (first_iteration) - first_iteration = false; - } - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glUseProgram(programBloom); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, colorBuffers[0]); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, pingpongColorbuffers[!horizontal]); - renderQuad(); + drawBloom(); glutSwapBuffers(); } -void init_particles() +void initAsteroids() +{ + int amount = asteroidAmount; + float radius = 15.0; + float offset = 25.0f; + + for (int i=0; i < amount; i++) + { + glm::mat4 model = glm::mat4(1.0f); + float angle = (float)i / (float)amount * 360.0f; + float displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; + + float x = sin(angle) * radius + displacement; + displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; + + float y = displacement * 0.4f; + displacement = (rand() % (int)(2 * offset * 100)) / 100.0f - offset; + + float z = cos(angle) * radius + displacement; + model = glm::translate(model, glm::vec3(x, y, z)); + + float scale = (rand() % 20) / 100.0f + 0.05; + model = glm::scale(model, glm::vec3(scale)); + + float rotAngle = (rand() % 360); + model = glm::rotate(model, rotAngle, glm::vec3(0.4f, 0.6f, 0.8f)); + + asteroids.push_back(model); + } + + unsigned int buffer; + glGenBuffers(1, &buffer); + glBindBuffer(GL_ARRAY_BUFFER, buffer); + glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &asteroids[0], GL_STATIC_DRAW); + + for (unsigned int i = 0; i < asteroid->meshes.size(); i++) + { + unsigned int VAO = asteroid->meshes[i].VAO; + glBindVertexArray(VAO); + // set attribute pointers for matrix (4 times vec4) + glEnableVertexAttribArray(5); + glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)0); + glEnableVertexAttribArray(6); + glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(sizeof(glm::vec4))); + glEnableVertexAttribArray(7); + glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(2 * sizeof(glm::vec4))); + glEnableVertexAttribArray(8); + glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void*)(3 * sizeof(glm::vec4))); + + glVertexAttribDivisor(5, 1); + glVertexAttribDivisor(6, 1); + glVertexAttribDivisor(7, 1); + glVertexAttribDivisor(8, 1); + + glBindVertexArray(0); + } +} + +void initParticles() { glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); @@ -661,7 +742,7 @@ void init_particles() lastTime = glutGet(GLUT_ELAPSED_TIME) / 1000.f; } -void init_bloom() +void initBloom() { glGenFramebuffers(1, &FBO); glBindFramebuffer(GL_FRAMEBUFFER, FBO); @@ -711,15 +792,42 @@ void init_bloom() } } +void initObjects() +{ + Object obj; + //ustalanie pozycji slonc (lightPos) + glm::mat4 sunModelMatrix = glm::mat4(1.0f); + sunModelMatrix = glm::translate(sunModelMatrix, sunPos); + sunModelMatrix = glm::scale(sunModelMatrix, glm::vec3(3.0f, 3.0f, 3.0f)); + obj.modelM = sunModelMatrix; + obj.invModelM = glm::inverse(sunModelMatrix); + obj.modelParent = sphere; + obj.textureID = sunTexture; + obj.shaderID = programSun; + obj.color = glm::vec3(3.5f, 3.8f, 3.8f); + objects.push_back(obj); + + glm::mat4 sunModelMatrix2 = glm::mat4(1.0f); + sunModelMatrix2 = glm::translate(sunModelMatrix2, sunPos2); + obj.modelM = sunModelMatrix2; + obj.invModelM = glm::inverse(sunModelMatrix2); + obj.color = glm::vec3(0.9f, 0.9f, 2.0f); + + objects.push_back(obj); + +} + void init() { glEnable(GL_DEPTH_TEST); programTex = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag"); + programNormal = shaderLoader.CreateProgram("shaders/shader_normal.vert", "shaders/shader_normal.frag"); programSkybox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag"); programSun = shaderLoader.CreateProgram("shaders/shader_sun.vert", "shaders/shader_sun.frag"); programBlur = shaderLoader.CreateProgram("shaders/shader_blur.vert", "shaders/shader_blur.frag"); programBloom = shaderLoader.CreateProgram("shaders/shader_bloom.vert", "shaders/shader_bloom.frag"); programParticle = shaderLoader.CreateProgram("shaders/shader_particle.vert", "shaders/shader_particle.frag"); + programAsteroid = shaderLoader.CreateProgram("shaders/shader_asteroid.vert", "shaders/shader_asteroid.frag"); glUseProgram(programBlur); glUniform1i(glGetUniformLocation(programBlur, "image"), 0); @@ -740,39 +848,40 @@ void init() //sphereContext.initFromOBJ(sphereModel); //cubeContext.initFromOBJ(cubeModel); //shipContext.initFromOBJ(shipModel); - shipTexture = Core::LoadTexture("textures/spaceship.png"); sunTexture = Core::LoadTexture("textures/sun.png"); earthTexture = Core::LoadTexture("textures/earth2.png"); moonTexture = Core::LoadTexture("textures/moon.png"); particleTexture = Core::LoadTexture("textures/sun.png"); skyboxTexture = loadCubemap(faces); - init_particles(); - init_bloom(); + initParticles(); + initBloom(); + initObjects(); + initAsteroids(); Light l1; l1.position = sunPos; l1.color = glm::vec3(0.8f, 0.8f, 0.7f); - l1.intensity = 7; + l1.intensity = 25; lights.push_back(l1); Light l2; l2.position = sunPos2; l2.color = glm::vec3(0.5f, 0.5f, 0.5f); - l2.intensity = 2; + l2.intensity = 15; lights.push_back(l2); Light l3; l3.position = glm::vec3(0); l3.color = glm::vec3(1.0f, 0.0f, 0.0f); - l3.intensity = 0.0001; + l3.intensity = 0.001; lights.push_back(l3); Light l4; l4.position = glm::vec3(0); l4.color = glm::vec3(1.0f, 0.0f, 0.0f); - l4.intensity = 0.0001; + l4.intensity = 0.001; lights.push_back(l4); } diff --git a/src/mesh.h b/src/mesh.h index caf8a5b..7cf134d 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -101,6 +101,53 @@ public: glActiveTexture(GL_TEXTURE0); } + // render the mesh + void DrawInstances(GLuint program, int amount) + { + // bind appropriate textures + unsigned int diffuseNr = 1; + unsigned int specularNr = 1; + unsigned int normalNr = 1; + unsigned int heightNr = 1; + for (unsigned int i = 0; i < textures.size(); i++) + { + glActiveTexture(GL_TEXTURE0 + i); // active proper texture unit before binding + // retrieve texture number (the N in diffuse_textureN) + string number; + string name = textures[i].type; + if (name == "texture_diffuse") + glUniform1i(glGetUniformLocation(program, "diffuseTexture"), i); + //number = std::to_string(diffuseNr++); + + else if (name == "texture_specular") + glUniform1i(glGetUniformLocation(program, "specularTexture"), i); + //number = std::to_string(specularNr++); // transfer unsigned int to stream + + else if (name == "texture_normal") + glUniform1i(glGetUniformLocation(program, "normalTexture"), i); + //number = std::to_string(normalNr++); // transfer unsigned int to stream + + else if (name == "texture_height") + glUniform1i(glGetUniformLocation(program, "heightTexture"), i); + //number = std::to_string(heightNr++); // transfer unsigned int to stream + + // now set the sampler to the correct texture unit + //glUniform1i(glGetUniformLocation(program, (name + number).c_str()), i); + //glUniform1i(glGetUniformLocation(program, "colorTexture"), i); + // and finally bind the texture + glBindTexture(GL_TEXTURE_2D, textures[i].id); + } + + //glUniformMatrix4fv(glGetUniformLocation(program, "model"), 1, GL_FALSE, (float*)&matrix); + // draw mesh + glBindVertexArray(VAO); + glDrawElementsInstanced(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0, amount); + glBindVertexArray(0); + + // always good practice to set everything back to defaults once configured. + glActiveTexture(GL_TEXTURE0); + } + private: // render data unsigned int VBO, EBO; diff --git a/src/model.h b/src/model.h index 2e22ef1..2d7bff5 100644 --- a/src/model.h +++ b/src/model.h @@ -49,6 +49,13 @@ public: meshes[i].Draw(shader); } + // draws Instances + void DrawInstances(GLuint shader, int amount) + { + for (unsigned int i = 0; i < meshes.size(); i++) + meshes[i].DrawInstances(shader, amount); + } + private: // loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector. void loadModel(string const& path)