bubbles #10
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
namespace Core
|
namespace Core
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
struct RenderContext
|
struct RenderContext
|
||||||
{
|
{
|
||||||
GLuint vertexArray;
|
GLuint vertexArray;
|
||||||
@ -22,6 +24,11 @@ namespace Core
|
|||||||
void initFromAssimpMesh(aiMesh* mesh);
|
void initFromAssimpMesh(aiMesh* mesh);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
std::vector<RenderContext> renderContexts;
|
||||||
|
glm::mat4 matrix;
|
||||||
|
int parent;
|
||||||
|
};
|
||||||
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
// vertexArray - jednowymiarowa tablica zawierajaca wartosci opisujace pozycje kolejnych wierzcholkow w jednym ciagu (x1, y1, z1, w1, x2, y2, z2, w2, ...)
|
||||||
// numVertices - liczba wierzcholkow do narysowania
|
// numVertices - liczba wierzcholkow do narysowania
|
||||||
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
// elementSize - liczba wartosci opisujacych pojedynczy wierzcholek (np. 3 gdy wierzcholek opisany jest trojka (x, y, z))
|
||||||
|
@ -19,6 +19,7 @@ GLuint programColor;
|
|||||||
GLuint programTexture;
|
GLuint programTexture;
|
||||||
GLuint textureSubmarine;
|
GLuint textureSubmarine;
|
||||||
GLuint textureBubble;
|
GLuint textureBubble;
|
||||||
|
GLuint textureFish;
|
||||||
unsigned int cubemapTexture, skyboxVAO;
|
unsigned int cubemapTexture, skyboxVAO;
|
||||||
unsigned int cubeVAO, cubeVBO;
|
unsigned int cubeVAO, cubeVBO;
|
||||||
|
|
||||||
@ -36,8 +37,21 @@ glm::mat4 cameraMatrix, perspectiveMatrix;
|
|||||||
|
|
||||||
Core::Shader_Loader shaderLoader;
|
Core::Shader_Loader shaderLoader;
|
||||||
Core::RenderContext submarineContext;
|
Core::RenderContext submarineContext;
|
||||||
|
Core::RenderContext fishContext;
|
||||||
Core::RenderContext bubbleContext;
|
Core::RenderContext bubbleContext;
|
||||||
|
|
||||||
|
std::vector<glm::vec3> keyPoints({
|
||||||
|
glm::vec3(15.0f, 5.0f, 15.0f),
|
||||||
|
glm::vec3(15.0f, 5.0f, -15.0f),
|
||||||
|
glm::vec3(-15.0f, 5.0f, -15.0f),
|
||||||
|
glm::vec3(-15.0f, 5.0f, 15.0f),
|
||||||
|
glm::vec3(15.0f, 5.0f, 15.0f),
|
||||||
|
});
|
||||||
|
|
||||||
|
std::vector<glm::quat> keyRotation;
|
||||||
|
|
||||||
|
std::vector<Core::Node> fish;
|
||||||
|
|
||||||
std::string skyboxTextures[6] = {
|
std::string skyboxTextures[6] = {
|
||||||
"models/skybox/right.jpg",
|
"models/skybox/right.jpg",
|
||||||
"models/skybox/left.jpg",
|
"models/skybox/left.jpg",
|
||||||
@ -210,6 +224,45 @@ glm::mat4 createCameraMatrix()
|
|||||||
return Core::createViewMatrixQuat(cameraPos, rotation);
|
return Core::createViewMatrixQuat(cameraPos, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 animationMatrix(float time) {
|
||||||
|
float speed = 1.;
|
||||||
|
time = time * speed;
|
||||||
|
std::vector<float> distances;
|
||||||
|
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(keyPoints[std::max(0, (index-1)%size)], keyPoints[(index) % size], keyPoints[(index + 1) % size], keyPoints[(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::mat4_cast(animationRotation);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color)
|
void drawObjectColor(Core::RenderContext context, glm::mat4 modelMatrix, glm::vec3 color)
|
||||||
{
|
{
|
||||||
GLuint program = programColor;
|
GLuint program = programColor;
|
||||||
@ -252,7 +305,7 @@ void renderScene()
|
|||||||
perspectiveMatrix = Core::createPerspectiveMatrix();
|
perspectiveMatrix = Core::createPerspectiveMatrix();
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f;
|
||||||
glUseProgram(skyboxProgram);
|
glUseProgram(skyboxProgram);
|
||||||
glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0);
|
glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0);
|
||||||
glm::mat4 transformation = perspectiveMatrix * cameraMatrix;
|
glm::mat4 transformation = perspectiveMatrix * cameraMatrix;
|
||||||
@ -261,22 +314,24 @@ void renderScene()
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
glUseProgram(skyboxProgram);
|
//glUseProgram(skyboxProgram);
|
||||||
glBindVertexArray(0);
|
//glBindVertexArray(0);
|
||||||
glBindVertexArray(cubeVAO);
|
//glBindVertexArray(cubeVAO);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
//glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
|
//glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
//glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
glBindVertexArray(0);
|
//glBindVertexArray(0);
|
||||||
|
|
||||||
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 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 submarineModelMatrix = glm::translate(cameraPos + cameraDir) * glm::mat4_cast(glm::inverse(rotation)) * submarineInitialTransformation;
|
||||||
//drawObjectColor(fishContext, fishModelMatrix, glm::vec3(0.6f));
|
|
||||||
|
glm::mat4 fishInitialTransformation = glm::translate(glm::vec3(0, 0, 0)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.25f));
|
||||||
|
glm::mat4 bubbleModelMatrix = glm::translate(glm::vec3(0, 0, 0)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.05f));
|
||||||
|
|
||||||
|
drawObjectTexture(bubbleContext, bubbleModelMatrix, textureBubble);
|
||||||
|
|
||||||
|
drawObjectTexture(fishContext, animationMatrix(time + 15), textureFish);
|
||||||
drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine);
|
drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine);
|
||||||
|
|
||||||
glm::mat4 bubbleInitialTransformation = glm::translate(glm::vec3(1, 0, -0.5)) * glm::rotate(glm::radians(180.0f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.005f));
|
|
||||||
drawObjectTexture(bubbleContext, bubbleInitialTransformation, textureBubble);
|
|
||||||
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +398,26 @@ void initSkybox()
|
|||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)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 < keyPoints.size() - 1; i++) {
|
||||||
|
//3.1
|
||||||
|
direction = glm::normalize(keyPoints[i + 1] - keyPoints[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));
|
||||||
|
keyRotation.push_back(glm::quat(1, -1, 1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
void initCube()
|
void initCube()
|
||||||
{
|
{
|
||||||
glGenVertexArrays(1, &cubeVAO);
|
glGenVertexArrays(1, &cubeVAO);
|
||||||
@ -364,10 +439,18 @@ void init()
|
|||||||
skyboxProgram = shaderLoader.CreateProgram((char *) "shaders/skybox.vert", (char *) "shaders/skybox.frag");
|
skyboxProgram = shaderLoader.CreateProgram((char *) "shaders/skybox.vert", (char *) "shaders/skybox.frag");
|
||||||
cubeProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag");
|
cubeProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag");
|
||||||
cubemapTexture = loadCubemap();
|
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);
|
loadModelToContext("models/submarine.obj", submarineContext);
|
||||||
textureSubmarine = Core::LoadTexture("textures/submarine.png");
|
textureSubmarine = Core::LoadTexture("textures/submarine.png");
|
||||||
loadModelToContext("models/sphere.obj", bubbleContext);
|
loadModelToContext("models/sphere.obj", bubbleContext);
|
||||||
textureBubble = Core::LoadTexture("textures/fish.png");
|
textureBubble = Core::LoadTexture("textures/bubble.png");
|
||||||
initCube();
|
initCube();
|
||||||
initSkybox();
|
initSkybox();
|
||||||
|
|
||||||
@ -386,7 +469,6 @@ void idle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
glutInit(&argc, argv);
|
glutInit(&argc, argv);
|
||||||
|
BIN
grafika_projekt/textures/bubble.png
Normal file
BIN
grafika_projekt/textures/bubble.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
Loading…
Reference in New Issue
Block a user