no i chuj

This commit is contained in:
Matraf 2022-01-23 19:19:09 +01:00
parent e7a5d0aa2b
commit fc6b24fb3d
14 changed files with 247 additions and 573 deletions

View File

@ -1,555 +0,0 @@
#define STB_IMAGE_IMPLEMENTATION
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "ext.hpp"
#include <iostream>
#include <cmath>
#include <vector>
#include <random>
#include "Shader_Loader.h"
#include "Render_Utils.h"
#include "Texture.h"
#include "Camera.h"
#include "SOIL/stb_image_aug.h"
GLuint skyboxProgram, skyboxBuffer;
GLuint bubbleProgram;
GLuint programColor;
GLuint programTexture;
GLuint textureSubmarine;
GLuint textureBubble;
GLuint textureFish;
unsigned int cubemapTexture, skyboxVAO;
unsigned int cubeVAO, cubeVBO;
float skyboxVerticeParameter = 50.0f;
float skyboxBoundary = 48.0f;
std::vector<glm::vec3> bubbleArray[300];
float old_x, old_y = -1;
glm::vec3 cursorDiff;
glm::vec3 lightDir = glm::normalize(glm::vec3(0.0f, skyboxVerticeParameter, 0.0f));
glm::vec3 cameraPos = glm::vec3(0, 0, 0);
glm::vec3 oldCameraPos = glm::vec3(0, 0, 5);
glm::vec3 cameraDir; // Wektor "do przodu" kamery
glm::vec3 cameraSide; // Wektor "w bok" kamery
float cameraAngle = 0;
glm::quat rotation = glm::quat(1, 0, 0, 0);
glm::mat4 cameraMatrix, perspectiveMatrix;
Core::Shader_Loader shaderLoader;
Core::RenderContext submarineContext;
Core::RenderContext fishContext;
Core::RenderContext bubbleContext;
std::vector<glm::vec3> fishKeyPoints({
glm::vec3(-18.0f, -10.0f, -10.0f),
glm::vec3(-10.0f, -5.0f, -12.0f),
glm::vec3(8.0f, -3.0f, -3.0f),
glm::vec3(5.0f, 0.0f, 3.0f),
glm::vec3(3.0f, 2.0f, 4.0f),
glm::vec3(8.0f, 5.0f, 9.0f),
glm::vec3(14.0f, 6.0f, 15.0f),
glm::vec3(15.0f, 12.0f, 12.0f),
glm::vec3(10.0f, 17.0f, 15.0f),
glm::vec3(5.0f, 10.0f, 7.0f),
glm::vec3(-1.0f, 4.0f, 8.0f),
glm::vec3(-8.0f, 0.0f, 3.0f),
glm::vec3(-12.0f, -6.0f, -3.0f),
glm::vec3(-15.0f, -8.0f, -6.0f),
glm::vec3(-18.0f, -10.0f, -10.0f),
});
std::vector<glm::quat> keyRotation;
std::vector<Core::Node> fish;
std::string skyboxTextures[6] = {
"models/skybox/right.jpg",
"models/skybox/left.jpg",
"models/skybox/top.jpg",
"models/skybox/bottom.jpg",
"models/skybox/front.jpg",
"models/skybox/back.jpg"
};
float cubeVertices[] = {
// positions // normals
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f
};
float skyboxVertices[] = {
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, skyboxVerticeParameter,
-skyboxVerticeParameter, skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, -skyboxVerticeParameter,
-skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter,
skyboxVerticeParameter, -skyboxVerticeParameter, skyboxVerticeParameter
};
bool isInBoundaries(glm::vec3 nextPosition) {
return nextPosition.z > -skyboxBoundary && nextPosition.z < skyboxBoundary&& nextPosition.y > -skyboxBoundary &&
nextPosition.y < skyboxBoundary&& nextPosition.x < skyboxBoundary&& nextPosition.x > -skyboxBoundary;
}
std::random_device rd; // obtain a random number from hardware
std::mt19937 gen(rd()); // seed the generator
std::uniform_int_distribution<> distr(-skyboxVerticeParameter, skyboxVerticeParameter); // define the range
std::vector<glm::vec3> genBubbleKeyPoints() {
float random1 = distr(gen);
float random2 = distr(gen);
std::vector<glm::vec3> bubbleKeyPoints({
glm::vec3(random1 , -skyboxVerticeParameter, random2),
glm::vec3(random1 , skyboxVerticeParameter, random2)
}
);
return bubbleKeyPoints;
};
void generateBubbleArray() {
for (int i = 0; i < 300; i++) {
bubbleArray[i] = genBubbleKeyPoints();
}
}
void keyboard(unsigned char key, int x, int y)
{
float angleSpeed = 10.f;
float moveSpeed = 1.0f;
glm::vec3 nextPosition;
switch (key)
{
case 'z': cursorDiff.z -= angleSpeed; break;
case 'x': cursorDiff.z += angleSpeed; break;
case 'w':
nextPosition = cameraPos + (cameraDir * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
}
break;
case 's':
nextPosition = cameraPos - (cameraDir * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
}
break;
case 'd':
nextPosition = cameraPos + (cameraSide * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
}
break;
case 'a':
nextPosition = cameraPos - (cameraSide * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
}
break;
}
}
void mouse(int x, int y)
{
if (old_x >= 0) {
cursorDiff.x = x - old_x;
cursorDiff.y = y - old_y;
}
old_x = x;
old_y = y;
if (x < 100 || x > 800 - 100) { //you can use values other than 100 for the screen edges if you like, kind of seems to depend on your mouse sensitivity for what ends up working best
old_x = 800 / 2; //centers the last known position, this way there isn't an odd jump with your cam as it resets
old_y = 800 / 2;
glutWarpPointer(800 / 2, 800 / 2); //centers the cursor
}
else if (y < 100 || y > 800 - 100) {
old_x = 800 / 2;
old_y = 800 / 2;
glutWarpPointer(800 / 2, 800 / 2);
}
}
glm::mat4 createCameraMatrix()
{
glm::quat rotation_x = glm::angleAxis(cursorDiff.y * 0.03f, glm::vec3(1, 0, 0));
cursorDiff.y = 0;
glm::quat rotation_y = glm::angleAxis(cursorDiff.x * 0.03f, glm::vec3(0, 1, 0));
cursorDiff.x = 0;
glm::quat rotation_z = glm::angleAxis(cursorDiff.z * 0.03f, glm::vec3(0, 0, 1));
cursorDiff.z = 0;
glm::quat rotationChange = rotation_x * rotation_y * rotation_z;
rotation = glm::normalize(rotationChange * rotation);
cameraDir = glm::inverse(rotation) * glm::vec3(0, 0, -1);
cameraSide = glm::inverse(rotation) * glm::vec3(1, 0, 0);
return Core::createViewMatrixQuat(cameraPos, rotation);
}
std::vector<glm::vec3> changeKeyPoints(std::vector<glm::vec3> keyPoints, glm::vec3 toChange) {
std::vector<glm::vec3> result;
int size = keyPoints.size();
glm::vec3 change;
for (int i = 0; i < size; i++) {
change.x = keyPoints[i].x + toChange.x;
change.y = keyPoints[i].y + toChange.y;
change.z = keyPoints[i].z + toChange.z;
result.push_back(change);
}
return result;
}
glm::mat4 animationMatrix(float time, glm::vec3 change, std::vector<glm::vec3> keyPoints, glm::vec3 scaleValue, float speed) {
time = time * speed;
std::vector<float> distances;
std::vector<glm::vec3> newKeyPoints = changeKeyPoints(keyPoints, change);
float timeStep = 0;
for (int i = 0; i < keyPoints.size() - 1; i++) {
timeStep += (keyPoints[i] - keyPoints[i + 1]).length();
distances.push_back((keyPoints[i] - keyPoints[i + 1]).length());
}
time = fmod(time, timeStep);
//index of first keyPoint
int index = 0;
while (distances[index] <= time) {
time = time - distances[index];
index += 1;
}
float t = time / distances[index];
int size = keyPoints.size();
int rotationSize = keyRotation.size();
glm::vec3 pos = glm::catmullRom(newKeyPoints[std::max(0, (index - 1) % size)], newKeyPoints[(index) % size], newKeyPoints[(index + 1) % size], newKeyPoints[(index + 2) % size], t);
glm::quat divideByFour = glm::quat(0.25f, 0.25f, 0.25f, 0.25f);
auto a1 = keyRotation[index % rotationSize] * glm::exp(-(glm::log(glm::inverse(keyRotation[index % rotationSize]) * keyRotation[std::max(0, (index - 1) % rotationSize)]) + glm::log(glm::inverse(keyRotation[index % rotationSize]) * keyRotation[(index + 1) % rotationSize])) * divideByFour);
auto a2 = keyRotation[(index + 1) % rotationSize] * glm::exp(-(glm::log(glm::inverse(keyRotation[(index + 1) % rotationSize]) * keyRotation[index % rotationSize]) + glm::log(glm::inverse(keyRotation[(index + 1) % rotationSize]) * keyRotation[(index + 2) % rotationSize])) * divideByFour);
auto animationRotation = glm::squad(keyRotation[index % rotationSize], keyRotation[(index + 1) % rotationSize], a1, a2, t);
glm::mat4 result = glm::translate(pos) * glm::scale(glm::vec3(scaleValue)) * glm::mat4_cast(animationRotation);
return result;
}
void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuint textureId, GLuint program)
{
glUseProgram(program);
glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z);
Core::SetActiveTexture(textureId, "textureSampler", program, 0);
glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation);
glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
Core::DrawContext(context);
glUseProgram(0);
}
void renderScene()
{
cameraMatrix = createCameraMatrix();
perspectiveMatrix = Core::createPerspectiveMatrix();
glClearColor(0.219f, 0.407f, 0.658f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f;
glUseProgram(skyboxProgram);
glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0);
glm::mat4 transformation = perspectiveMatrix * cameraMatrix;
glUniformMatrix4fv(glGetUniformLocation(skyboxProgram, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation);
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glm::mat4 submarineInitialTransformation = glm::translate(glm::vec3(0, -0.5, -0.4)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f));
glm::mat4 submarineModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * submarineInitialTransformation;
glm::mat4 bubbleInitialTransformation = glm::translate(glm::vec3(0, -0.5, -0.4)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.5f));
glm::vec3 change1 = glm::vec3(0, 3, 0);
glm::vec3 change2 = glm::vec3(0, 0, 0);
glm::vec3 change3 = glm::vec3(3, 0, 0);
glm::vec3 change4 = glm::vec3(0, 2, 1);
glm::vec3 change0 = glm::vec3(0, 0, 0);
for (int j = 0; j < 100; j++) {
drawObjectTexture(bubbleContext, animationMatrix(time + j, change0, bubbleArray[j], glm::vec3(0.04f), 0.2f), cubemapTexture, bubbleProgram);
}
for (int i = 0; i < 5; i++) {
if (time > -10) {
drawObjectTexture(fishContext, animationMatrix(time + 15, change1, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture);
drawObjectTexture(fishContext, animationMatrix(time + 15, change2, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture);
drawObjectTexture(fishContext, animationMatrix(time + 15, change3, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture);
drawObjectTexture(fishContext, animationMatrix(time + 15, change4, fishKeyPoints, glm::vec3(0.25f), 1.f), textureFish, programTexture);
time -= 6;
}
}
//drawObjectTexture(bubbleContext, submarineInitialTransformation, cubemapTexture, bubbleProgram);
drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine, programTexture);
glutSwapBuffers();
}
void loadModelToContext(std::string path, Core::RenderContext& context)
{
Assimp::Importer import;
const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{
std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl;
return;
}
context.initFromAssimpMesh(scene->mMeshes[0]);
}
unsigned int loadCubemap()
{
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
int width, height, nrChannels;
for (unsigned int i = 0; i < 6; i++)
{
unsigned char* data = stbi_load(skyboxTextures[i].c_str(), &width, &height, &nrChannels, STBI_rgb_alpha);
if (data)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data
);
stbi_image_free(data);
}
else
{
std::cout << stbi_failure_reason() << std::endl;
std::cout << "Cubemap tex failed to load at path: " << skyboxTextures[i] << std::endl;
stbi_image_free(data);
}
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return textureID;
}
void initSkybox()
{
glGenVertexArrays(1, &skyboxVAO);
glBindVertexArray(skyboxVAO);
glGenBuffers(1, &skyboxBuffer);
glBindBuffer(GL_ARRAY_BUFFER, skyboxBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
GLuint vPosition = glGetAttribLocation(skyboxProgram, "aPos");
glEnableVertexAttribArray(vPosition);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(skyboxVertices), skyboxVertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
}
void initKeyRotation() {
glm::vec3 oldDirection = glm::vec3(0, 0, 1);
glm::quat oldRotationCamera = glm::quat(1, 0, 0, 0);
glm::vec3 direction;
glm::quat rotation;
for (int i = 0; i < fishKeyPoints.size() - 1; i++) {
//3.1
direction = glm::normalize(fishKeyPoints[i + 1] - fishKeyPoints[i]);
//3.2
rotation = glm::normalize(glm::rotationCamera(oldDirection, direction) * oldRotationCamera);
//3.3
keyRotation.push_back(rotation);
//3.4
oldDirection = direction;
oldRotationCamera = rotation;
}
keyRotation.push_back(glm::quat(1, 0, 0, 0));
}
void initCube()
{
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), &cubeVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
}
void init()
{
glEnable(GL_DEPTH_TEST);
programColor = shaderLoader.CreateProgram((char*)"shaders/shader_color.vert", (char*)"shaders/shader_color.frag");
programTexture = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.frag");
skyboxProgram = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag");
bubbleProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag");
cubemapTexture = loadCubemap();
loadModelToContext("models/submarine.obj", submarineContext);
textureSubmarine = Core::LoadTexture("textures/submarine.png");
loadModelToContext("models/fish.obj", fishContext);
textureFish = Core::LoadTexture("textures/fish.png");
initKeyRotation();
loadModelToContext("models/submarine.obj", submarineContext);
textureSubmarine = Core::LoadTexture("textures/submarine.png");
loadModelToContext("models/sphere.obj", bubbleContext);
textureBubble = Core::LoadTexture("textures/bubble.png");
generateBubbleArray();
initCube();
initSkybox();
}
void shutdown()
{
shaderLoader.DeleteProgram(programColor);
shaderLoader.DeleteProgram(programTexture);
shaderLoader.DeleteProgram(skyboxProgram);
shaderLoader.DeleteProgram(bubbleProgram);
}
void idle()
{
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(800, 800);
glutCreateWindow("Water and shit");
glewInit();
init();
glutKeyboardFunc(keyboard);
glutPassiveMotionFunc(mouse);
glutDisplayFunc(renderScene);
glutIdleFunc(idle);
glutSetCursor(GLUT_CURSOR_NONE);
glutMainLoop();
shutdown();
return 0;
}

View File

@ -29,7 +29,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@ -154,6 +154,7 @@
<ClCompile Include="src\SOIL\stb_image_aug.c" />
<ClCompile Include="src\Texture.cpp" />
<ClCompile Include="src\Terrain.cpp" />
<ClCompile Include="src\TerrainRenderer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\RawModel.h" />
@ -170,6 +171,7 @@
<ClInclude Include="src\SOIL\stb_image_aug.h" />
<ClInclude Include="src\Texture.h" />
<ClInclude Include="src\Terrain.h" />
<ClInclude Include="src\TerrainRenderer.h" />
</ItemGroup>
<ItemGroup>
<None Include="assimp-vc141-mt.dll" />

View File

@ -51,6 +51,9 @@
<ClCompile Include="src\RawModel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\TerrainRenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Shader_Loader.h">
@ -95,6 +98,9 @@
<ClInclude Include="src\RawModel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\TerrainRenderer.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="shaders\skybox.frag" />

View File

@ -2,7 +2,6 @@
uniform sampler2D textureSampler;
uniform vec3 lightDir;
uniform vec3 lightPos;
uniform vec3 cameraPos;
uniform vec3 objectColor;

View File

@ -0,0 +1,36 @@
#version 400 core
in vec2 pass_textureCoordinates;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;
out vec4 out_Color;
uniform sampler2D modelTexture;
uniform float shineDamper;
uniform float reflectivity;
void main(void){
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitLightVector = normalize(toLightVector);
float nDotl = dot(unitNormal,unitLightVector);
float brightness = max(nDotl,0.2);
vec3 diffuse = brightness * vec3(1.0, 1.0, 1.0); //Tu by³a zmiana
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
float specularFactor = dot(reflectedLightDirection , unitVectorToCamera);
specularFactor = max(specularFactor,0.0);
float dampedFactor = pow(specularFactor,shineDamper);
vec3 finalSpecular = dampedFactor * reflectivity * vec3(1.0, 1.0, 1.0); //Tu by³a zmiana
out_Color = vec4(diffuse,1.0) * texture(modelTexture,pass_textureCoordinates) + vec4(finalSpecular,1.0);
}

View File

@ -0,0 +1,28 @@
#version 400 core
in vec3 position;
in vec2 textureCoordinates;
in vec3 normal;
out vec2 pass_textureCoordinates;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightDir;
void main(void){
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoordinates = textureCoordinates * 40.0;
surfaceNormal = (transformationMatrix * vec4(normal,0.0)).xyz;
toLightVector = lightDir - worldPosition.xyz;
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
}

View File

@ -3,4 +3,12 @@
RawModel::RawModel(int vaoID, int vertexCount) {
this->vaoID = vaoID;
this->vertexCount = vertexCount;
}
int RawModel::getVertexCount() {
return vertexCount;
}
int RawModel::getVaoID() {
return vaoID;
}

View File

@ -4,6 +4,8 @@ class RawModel
public:
RawModel() = default;
RawModel(int vaoID, int vertexCount);
int getVertexCount();
int getVaoID();
private:
int vaoID;
int vertexCount;

View File

@ -1,18 +1,19 @@
#include "Terrain.h"
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
const float Terrain::SIZE = 800.f;
const float Terrain::SIZE = 400.f;
const int Terrain::VERTEX_COUNT = 128;
const int Terrain::COUNT = Terrain::VERTEX_COUNT * Terrain::VERTEX_COUNT;
Terrain::Terrain(int gridX, int gridZ, GLuint textureID) {
Terrain::Terrain(int gridX, int gridZ, GLuint textureID, HeightGenerator heightGenerator) {
x = gridX * SIZE;
z = gridZ * SIZE;
texture = textureID;
model = generateTerrain();
this->heightGenerator = heightGenerator;
}
RawModel Terrain::generateTerrain() {
@ -26,17 +27,18 @@ RawModel Terrain::generateTerrain() {
vertices[vertexPointer * 3] = float(j) / float(VERTEX_COUNT - 1) * SIZE;
vertices[vertexPointer * 3 + 1] = 0;
vertices[vertexPointer * 3 + 2] = float(i) / float(VERTEX_COUNT - 1) * SIZE;
normals[vertexPointer * 3] = 0;
normals[vertexPointer * 3 + 1] = 1;
normals[vertexPointer * 3 + 2] = 0;
textureCoords[vertexPointer * 2] = float(j) / float(VERTEX_COUNT - 1) * SIZE;
textureCoords[vertexPointer * 2 + 1] = float(i) / float(VERTEX_COUNT - 1) * SIZE;
glm::vec3 normal = calculateNormal(j, i);
normals[vertexPointer * 3] = normal.x;
normals[vertexPointer * 3 + 1] = normal.y;
normals[vertexPointer * 3 + 2] = normal.z;
textureCoords[vertexPointer * 2] = float(j) / float(VERTEX_COUNT - 1);// *SIZE;
textureCoords[vertexPointer * 2 + 1] = float(i) / float(VERTEX_COUNT - 1);// *SIZE;
vertexPointer++;
}
}
int pointer = 0;
for (int gz = 0; gz < VERTEX_COUNT; gz++) {
for (int gx = 0; gx < VERTEX_COUNT; gx++) {
for (int gz = 0; gz < VERTEX_COUNT - 1; gz++) {
for (int gx = 0; gx < VERTEX_COUNT - 1; gx++) {
int topLeft = gz * VERTEX_COUNT + gx;
int topRight = topLeft + 1;
int bottomLeft = (gz + 1) * VERTEX_COUNT + gx;
@ -71,3 +73,32 @@ void Terrain::storeDataInAttributeList(int attributeNumber, int coordinateSize,
glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
RawModel Terrain::getModel() {
return model;
}
GLuint Terrain::getTexture() {
return texture;
}
glm::vec3 Terrain::calculateNormal(int x, int z) {
float heightL = getHeight(x - 1, z);
float heightR = getHeight(x + 1, z);
float heightD = getHeight(x, z - 1);
float heightU = getHeight(x, z + 1);
glm::vec3 normal = glm::vec3(heightL - heightR, 2.f, heightD - heightU);
return glm::normalize(normal);
}
float Terrain::getHeight(int x, int z) {
return heightGenerator.generateHeight(x, z);
}
int Terrain::getX() {
return x;
}
int Terrain::getZ() {
return z;
}

View File

@ -1,19 +1,31 @@
#pragma once
#include "RawModel.h"
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "HeightGenerator.h"
class Terrain
{
public:
Terrain() = default;
Terrain(int gridX, int gridZ, GLuint textureID);
Terrain(int gridX, int gridZ, GLuint textureID, HeightGenerator heightGenerator);
RawModel getModel();
GLuint getTexture();
int getX();
int getZ();
private:
static const float SIZE;
static const int VERTEX_COUNT;
static const int COUNT;
float x;
float z;
HeightGenerator heightGenerator;
GLuint texture;
RawModel model;
RawModel generateTerrain();
void storeDataInAttributeList(int attributeNumber, int coordinateSize, float data[]);
glm::vec3 calculateNormal(int x, int z);
float getHeight(int x, int z);
};

View File

@ -0,0 +1,56 @@
#include "TerrainRenderer.h"
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
TerrainRenderer::TerrainRenderer(GLuint terrainProgram,
glm::mat4 projectionMatrix,
Terrain terrain,
glm::mat4 transformationMatrix,
glm::mat4 viewMatrix,
glm::vec3 lightDir,
// glm::vec3 lightColour,
float shineDamper,
float reflectivity) {
this->terrainProgram = terrainProgram;
this->projectionMatrix = projectionMatrix;
this->terrain = terrain;
this->transformationMatrix = transformationMatrix;
this->viewMatrix = viewMatrix;
this->lightDir = lightDir;
// this->lightColour = lightColour;
this->shineDamper = shineDamper;
this->reflectivity = reflectivity;
}
void TerrainRenderer::render() {
initShader();
prepareTerrain();
glDrawElements(GL_TRIANGLES, terrain.getModel().getVertexCount(), GL_UNSIGNED_INT, 0);
}
void TerrainRenderer::initShader() {
glUseProgram(terrainProgram);
glBindAttribLocation(terrainProgram, 0, "position");
glBindAttribLocation(terrainProgram, 1, "textureCoordinates");
glBindAttribLocation(terrainProgram, 2, "normal");
glUniformMatrix4fv(glGetUniformLocation(terrainProgram, "transformationMatrix"), 1, GL_FALSE, (float*) &transformationMatrix);
glUniformMatrix4fv(glGetUniformLocation(terrainProgram, "projectionMatrix"), 2, GL_FALSE, (float*) &projectionMatrix);
glUniformMatrix4fv(glGetUniformLocation(terrainProgram, "viewMatrix"), 3, GL_FALSE, (float*) &viewMatrix);
glUniform3f(glGetUniformLocation(terrainProgram, "lightDir"), lightDir.x, lightDir.y, lightDir.z);
// glUniform3f(glGetUniformLocation(terrainProgram, "lightColour"), lightColour.x, lightColour.y, lightColour.z);
glUniform1f(glGetUniformLocation(terrainProgram, "shineDamper"), shineDamper);
glUniform1f(glGetUniformLocation(terrainProgram, "reflectivity"), reflectivity);
glUseProgram(0);
}
void TerrainRenderer::prepareTerrain() {
RawModel rawModel = terrain.getModel();
glBindVertexArray(rawModel.getVaoID());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, terrain.getTexture());
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "Terrain.h"
#include "glm.hpp"
#include "glew.h"
class TerrainRenderer
{
public:
TerrainRenderer() = default;
TerrainRenderer(GLuint terrainProgram,
glm::mat4 projectionMatrix,
Terrain terrain,
glm::mat4 transformationMatrix,
glm::mat4 viewMatrix,
glm::vec3 lightDir,
// glm::vec3 lightColour,
float shineDamper,
float reflectivity);
void render();
private:
void prepareTerrain();
void initShader();
GLuint terrainProgram;
glm::mat4 projectionMatrix;
Terrain terrain;
glm::mat4 transformationMatrix;
glm::mat4 viewMatrix;
glm::vec3 lightDir;
// glm::vec3 lightColour;
float shineDamper;
float reflectivity;
};

View File

@ -14,11 +14,14 @@
#include "SOIL/stb_image_aug.h"
#include "HeightGenerator.h"
#include "Terrain.h"
#include "TerrainRenderer.h"
GLuint skyboxProgram, skyboxBuffer;
GLuint bubbleProgram;
GLuint programTexture;
GLuint terrainProgram;
GLuint textureSubmarine;
GLuint textureBubble;
GLuint textureFish;
@ -27,7 +30,7 @@ unsigned int cubemapTexture, skyboxVAO;
unsigned int cubeVAO, cubeVBO;
float skyboxVerticeParameter = 50.0f;
float skyboxBoundary = 48.0f;
float skyboxBoundary = 480.0f;
std::vector<glm::vec3> bubbleArray[300];
float old_x, old_y = -1;
@ -49,6 +52,9 @@ Core::RenderContext submarineContext;
Core::RenderContext fishContext;
Core::RenderContext bubbleContext;
GLuint textureID;
HeightGenerator heightGenerator;
std::vector<glm::vec3> fishKeyPoints({
glm::vec3(-18.0f, -10.0f, -10.0f),
glm::vec3(-10.0f, -5.0f, -12.0f),
@ -345,7 +351,7 @@ void drawObjectTexture(Core::RenderContext context, glm::mat4 modelMatrix, GLuin
void renderScene()
{
{
cameraMatrix = createCameraMatrix();
perspectiveMatrix = Core::createPerspectiveMatrix();
@ -359,12 +365,14 @@ void renderScene()
glUniformMatrix4fv(glGetUniformLocation(skyboxProgram, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation);
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glm::mat4 submarineInitialTransformation = glm::translate(glm::vec3(0, -0.5, -0.4)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f));
glm::mat4 submarineModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * submarineInitialTransformation;
@ -497,6 +505,8 @@ void init()
programTexture = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.frag");
skyboxProgram = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag");
bubbleProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag");
terrainProgram = shaderLoader.CreateProgram((char*)"shaders/terrainShader.vert", (char*)"shaders/terrainShader.frag");
cubemapTexture = loadCubemap();
loadModelToContext("models/submarine.obj", submarineContext);
@ -514,9 +524,12 @@ void init()
initCube();
initSkybox();
//GLuint textureID = Core::LoadTexture('textura_terrain');
//Terrain terrain = new Terrain(0, 0, textureID);
textureID = Core::LoadTexture("textures/terrain.png");
Terrain terrain(0, 0, textureID, heightGenerator);
glm::mat4 terrainTransformation = glm::translate(glm::vec3(terrain.getX(), 0, terrain.getZ())) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0));
TerrainRenderer terrainRenderer(terrainProgram, perspectiveMatrix, terrain, terrainTransformation, -cameraMatrix, lightDir, 1.f, 0.f);
terrainRenderer.render();
}
void shutdown()

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB