change fog color and fix particle position

This commit is contained in:
Matraf 2022-01-26 17:06:14 +01:00
commit 22eddad225
35 changed files with 40470 additions and 342 deletions

View File

@ -1,16 +0,0 @@
#pragma once
#include "glew.h"
#include "freeglut.h"
#include <string>
#include <iostream>
namespace Core
{
GLuint LoadTexture(const char* filepath);
// textureID - identyfikator tekstury otrzymany z funkcji LoadTexture
// shaderVariableName - nazwa zmiennej typu 'sampler2D' w shaderze, z ktora ma zostac powiazana tekstura
// programID - identyfikator aktualnego programu karty graficznej
// textureUnit - indeks jednostki teksturujacej - liczba od 0 do 7. Jezeli uzywa sie wielu tekstur w jednym shaderze, to kazda z nich nalezy powiazac z inna jednostka.
void SetActiveTexture(GLuint textureID, const char* shaderVariableName, GLuint programID, int textureUnit);

View File

@ -142,7 +142,9 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\Particle.cpp" />
<ClCompile Include="src\Engine.cpp" />
<ClCompile Include="src\Particle.cpp" />
<ClCompile Include="src\HeightGenerator.cpp" />
<ClCompile Include="src\Camera.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\Render_Utils.cpp" />
@ -152,10 +154,15 @@
<ClCompile Include="src\SOIL\SOIL.c" />
<ClCompile Include="src\SOIL\stb_image_aug.c" />
<ClCompile Include="src\Texture.cpp" />
<ClCompile Include="src\Terrain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\Engine.h" />
<ClInclude Include="src\HeightGenerator.h" />
<ClInclude Include="src\Particle.h" />
<ClInclude Include="src\Camera.h" />
<ClInclude Include="src\mesh.h" />
<ClInclude Include="src\model.h" />
<ClInclude Include="src\objload.h" />
<ClInclude Include="src\Render_Utils.h" />
<ClInclude Include="src\Shader_Loader.h" />
@ -166,7 +173,7 @@
<ClInclude Include="src\SOIL\stbi_DDS_aug_c.h" />
<ClInclude Include="src\SOIL\stb_image_aug.h" />
<ClInclude Include="src\Texture.h" />
<ClInclude Include="Textures.h" />
<ClInclude Include="src\Terrain.h" />
</ItemGroup>
<ItemGroup>
<None Include="assimp-vc141-mt.dll" />

View File

@ -42,7 +42,17 @@
<ClCompile Include="src\Render_Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<<<<<<< HEAD
<ClCompile Include="src\Particle.cpp">
=======
<ClCompile Include="src\HeightGenerator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Terrain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Engine.cpp">
>>>>>>> plants-new
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
@ -80,7 +90,19 @@
<ClInclude Include="src\objload.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Textures.h">
<ClInclude Include="src\HeightGenerator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Terrain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\mesh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\model.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Engine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\Particle.h">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
v 0 50 0
v 100 30 0
v 0 1 100
v 100 100 100
vt 0 0
vt 20 0
vt 0 20
vt 20 20
vn 0.61 3.67 -0.78
vn 0.99 2.89 -0.13
vn 0.14 7.02 -0.98
vn 0.5 7.3 -0.86
s off
f 1/1/1 3/3/3 2/2/2
f 2/2/2 3/3/3 4/4/4

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,6 @@
uniform sampler2D textureSampler;
uniform vec3 lightDir;
uniform vec3 lightPos;
uniform vec3 cameraPos;
uniform vec3 objectColor;
@ -10,7 +9,7 @@ in vec3 fragPos;
in vec3 interpNormal;
in vec2 interpTexCoord;
float near = 0.02f;
float near = 0.01f;
float far = 100.0f;
float linearizeDepth(float depth)
@ -36,6 +35,9 @@ void main()
vec3 R = reflect(-normalize(lightDir),normal);
float ambient = 0.2;
float specular = pow(max(0,dot(R,V)),1000);
//gl_FragColor = vec4(color*(ambient + (1-ambient)*diffuse)+vec3(1)*specular*0.2, 1.0);
gl_FragColor = vec4(color*(ambient + (1-ambient)*diffuse)+vec3(1)*specular*0.2, 1.0) * (1.0f - depth) + vec4(depth * vec3(0.0f, 0.109f, 0.447f), 1.0f);;
}

View File

@ -5,7 +5,7 @@ in vec3 TexCoords;
uniform samplerCube skybox;
float near = 0.02f;
float near = 0.01f;
float far = 100.0f;
float linearizeDepth(float depth)

View File

@ -5,7 +5,7 @@
namespace Core
{
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 200.0f);
glm::mat4 createPerspectiveMatrix(float zNear = 0.1f, float zFar = 800.f);
// position - pozycja kamery
// forward - wektor "do przodu" kamery (jednostkowy)

View File

@ -0,0 +1,221 @@
#include "Engine.h"
void Core::Engine::initShaderPrograms() {
this->textureShader = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.frag");
this->skyboxShader = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag");
this->bubbleShader = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.frag");
this->particleShader = shaderLoader.CreateProgram((char*)"shaders/particles.vert", (char*)"shaders/particles.frag");
}
void Core::Engine::shutdownShaderPrograms() {
shaderLoader.DeleteProgram(this->textureShader);
shaderLoader.DeleteProgram(this->skyboxShader);
shaderLoader.DeleteProgram(this->bubbleShader);
shaderLoader.DeleteProgram(this->particleShader);
}
void Core::Engine::initRenderContexts() {
loadModelToContext("models/fish.obj", this->fishContext);
loadModelToContext("models/submarine.obj", this->submarineContext);
loadModelToContext("models/sphere.obj", this->bubbleContext);
loadModelToContext("models/arch.obj", this->archContext);
loadModelToContext("models/coral01.obj", this->coral1Context);
loadModelToContext("models/plant1.obj", this->plant1Context);
loadModelToContext("models/plant2.obj", this->plant2Context);
loadModelToContext("models/plant3.obj", this->plant3Context);
loadModelToContext("models/rocktower1.obj", this->rocktower1Context);
this->terrain = Terrain(this->heightGenerator);
obj::Model model = this->terrain.generateTerrain();
this->terrainContext.initFromOBJ(model);
}
void Core::Engine::loadTextures() {
this->fishTexture = LoadTexture("textures/fish.png");
this->submarineTexture = LoadTexture("textures/submarine.png");
this->bubbleTexture = LoadTexture("textures/bubble.png");
this->terrainTexture = LoadTexture("textures/sand2.jpg");
this->archTexture = LoadTexture("textures/arch.png");
this->coral1Texture = LoadTexture("textures/coral01.png");
this->plant1Texture = LoadTexture("textures/plant1.png");
this->plant2Texture = LoadTexture("textures/plant2.png");
this->plant3Texture = LoadTexture("textures/plant3.png");
this->rocktower1Texture = LoadTexture("textures/rocktower1.png");
this->skyboxTexture = loadCubemap();
}
void Core::Engine::initCube() {
GLuint cubeVAO, cubeVBO;
glGenVertexArrays(1, &cubeVAO);
glGenBuffers(1, &cubeVBO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(this->cubeVertices), &this->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 Core::Engine::initSkybox() {
this->initCube();
glGenVertexArrays(1, &this->skyboxVAO);
glBindVertexArray(this->skyboxVAO);
glGenBuffers(1, &this->skyboxVBO);
glBindBuffer(GL_ARRAY_BUFFER, this->skyboxVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(this->skyboxVertices), &this->skyboxVertices, GL_STATIC_DRAW);
GLuint vPosition = glGetAttribLocation(this->skyboxShader, "aPos");
glEnableVertexAttribArray(vPosition);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(this->skyboxVertices), this->skyboxVertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
}
void Core::Engine::initRandomGenerator(std::default_random_engine gen, std::uniform_int_distribution<> distr) {
this->gen = gen;
this->distr = distr;
}
std::vector<glm::vec3> Core::Engine::genBubbleKeyPoints() {
float random1 = this->distr(this->gen);
float random2 = this->distr(this->gen);
std::vector<glm::vec3> bubbleKeyPoints({
glm::vec3(random1 , -this->skyboxVerticeParameter, random2),
glm::vec3(random1 , this->skyboxVerticeParameter, random2)
}
);
return bubbleKeyPoints;
};
void Core::Engine::generateBubbleArray() {
for (int i = 0; i < 300; i++) {
this->bubbleArray[i] = this->genBubbleKeyPoints();
}
}
void Core::Engine::generateObjectArray() {
std::uniform_int_distribution<> distr(-64, 64);
for (int i = 0; i < 200; i++) {
int random1 = distr(this->gen);
int random2 = distr(this->gen);
float height = -this->skyboxVerticeParameter + this->terrain.heightTable[abs(random1)][abs(random2)] + 15;
this->objectArray[i] = glm::vec3(random1, height, random2) * glm::vec3(3,1,3);
}
}
void Core::Engine::generateObjectSize() {
std::uniform_real_distribution<> distr(0.1f, 0.25f);
for (int i = 0; i < 200; i++) {
float random = distr(this->gen);
objectSize.push_back(random);
}
}
void Core::Engine::generateObjectRotation() {
std::uniform_real_distribution<> distr(0.0f, 360.0f);
for (int i = 0; i < 200; i++) {
float random = distr(this->gen);
objectRotation.push_back(random);
}
}
void Core::Engine::initBubbles() {
this->generateBubbleArray();
}
const float Core::Engine::cubeVertices[216] = {
// 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
};
const float Core::Engine::skyboxVerticeParameter = 200.0f;
const float Core::Engine::skyboxVertices[108] = {
-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
};

View File

@ -0,0 +1,49 @@
#pragma once
#include "glm.hpp"
#include "glew.h"
#include <map>
#include <string>
#include "Shader_Loader.h"
#include "Texture.h"
#include "Render_Utils.h"
#include "Terrain.h"
#include "HeightGenerator.h"
#include <random>
namespace Core {
class Engine {
public:
GLuint textureShader, skyboxShader, bubbleShader, particleShader;
GLuint submarineTexture, bubbleTexture, fishTexture, terrainTexture, skyboxTexture, plant1Texture, plant2Texture, plant3Texture, coral1Texture, rocktower1Texture, archTexture ;
GLuint skyboxVAO;
Core::RenderContext submarineContext, fishContext, bubbleContext, terrainContext, plant1Context, plant2Context, plant3Context, coral1Context, rocktower1Context, archContext;
std::vector<glm::vec3> bubbleArray[300];
std::vector<float> objectSize;
std::vector<float> objectRotation;
glm::vec3 objectArray[200];
void initShaderPrograms();
void shutdownShaderPrograms();
void initRenderContexts();
void loadTextures();
void initSkybox();
void initBubbles();
void generateObjectArray();
void generateObjectSize();
void generateObjectRotation();
Terrain terrain;
void initRandomGenerator(std::default_random_engine gen, std::uniform_int_distribution<> distr);
static const float skyboxVerticeParameter;
private:
HeightGenerator heightGenerator;
GLuint skyboxVBO;
Shader_Loader shaderLoader;
static const float cubeVertices[216], skyboxVertices[108];
std::uniform_int_distribution<> distr;
std::default_random_engine gen;
void initCube();
void generateBubbleArray();
std::vector<glm::vec3> genBubbleKeyPoints();
};
}

View File

@ -0,0 +1,55 @@
#include "HeightGenerator.h"
#include <random>
#include <iostream>
#include <math.h>
# define MY_PI 3.1415927
std::random_device rd; // obtain a random number from hardware
const int HeightGenerator::SEED = rd();
float HeightGenerator::generateHeight(int x, int z) {
float total = 0;
int p = 0.25f;
for (int i = 0; i < 5; i++) {
float freq = pow(2, i);
float amp = pow(p, i);
total += getInterpolatedNoise(x * freq, z * freq) * amp;
}
return total;
}
float HeightGenerator::getInterpolatedNoise(float x, float z) {
int intX = int(x);
int intZ = int(z);
float fracX = x - intX;
float fracZ = z - intZ;
float v1 = getSmoothNoise(intX, intZ);
float v2 = getSmoothNoise(intX + 1, intZ);
float v3 = getSmoothNoise(intX, intZ + 1);
float v4 = getSmoothNoise(intX + 1, intZ + 1);
float i1 = interpolate(v1, v2, fracX);
float i2 = interpolate(v3, v4, fracX);
return interpolate(i1, i2, fracZ);
}
float HeightGenerator::interpolate(float a, float b, float blend) {
double theta = blend * MY_PI;
float f = float(1.f - cos(theta)) * 0.5f;
return a * (1 - f) + b * f;
}
float HeightGenerator::getSmoothNoise(int x, int z) {
float corners = float(getNoise(x - 1, z - 1) + getNoise(x + 1, z - 1) + getNoise(x - 1, z + 1) + getNoise(x + 1, z + 1)) / 16;
float sides = float(getNoise(x - 1, z) + getNoise(x + 1, z) + getNoise(x, z - 1) + getNoise(x, z + 1)) / 8;
float center = float(getNoise(x, z)) / 4;
return corners + sides + center;
}
float HeightGenerator::getNoise(int x, int z) {
std::mt19937 gen(SEED + x * 49632 + z * 325176);
std::uniform_real_distribution<> distr(-3, 3);
return distr(gen);
}

View File

@ -0,0 +1,13 @@
#pragma once
class HeightGenerator
{
public:
float generateHeight(int x, int z);
static const int SEED;
private:
float getInterpolatedNoise(float x, float z);
float getSmoothNoise(int x, int z);
float interpolate(float a, float b, float blend);
float getNoise(int x, int z);
};

View File

@ -8,7 +8,6 @@
#include <assimp/scene.h>
#include <assimp/postprocess.h>
void Core::RenderContext::initFromOBJ(obj::Model& model)
{
vertexArray = 0;
@ -19,7 +18,7 @@ void Core::RenderContext::initFromOBJ(obj::Model& model)
unsigned int vertexTexBufferSize = sizeof(float) * model.texCoord.size();
size = model.faces["default"].size();
unsigned int vertexElementBufferSize = sizeof(unsigned short) * size;
unsigned int vertexElementBufferSize = sizeof(unsigned int) * size;
glGenVertexArrays(1, &vertexArray);
@ -167,3 +166,80 @@ void Core::DrawContext(Core::RenderContext& context)
);
glBindVertexArray(0);
}
void Core::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]);
}
GLuint Core::loadCubemap()
{
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"
};
GLuint 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 Core::drawObjectTexture(
Core::RenderContext context,
glm::mat4 modelMatrix,
GLuint textureId,
GLuint program,
glm::vec3 lightDir,
glm::mat4 cameraMatrix,
glm::mat4 perspectiveMatrix
) {
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);
}

View File

@ -5,12 +5,15 @@
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "SOIL/stb_image_aug.h"
#include "Texture.h"
#define STB_IMAGE_IMPLEMENTATION
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
namespace Core
{
struct RenderContext
{
@ -76,4 +79,18 @@ namespace Core
void DrawVertexArray(const VertexData & data);
void DrawContext(RenderContext& context);
void loadModelToContext(std::string path, Core::RenderContext& context);
void drawObjectTexture(
Core::RenderContext context,
glm::mat4 modelMatrix,
GLuint textureId,
GLuint program,
glm::vec3 lightDir,
glm::mat4 cameraMatrix,
glm::mat4 perspectiveMatrix
);
GLuint loadCubemap();
}

View File

@ -0,0 +1,72 @@
#include "Terrain.h"
const float Terrain::SIZE = 50.f;
const int Terrain::VERTEX_COUNT = 64;
const int Terrain::COUNT = Terrain::VERTEX_COUNT * Terrain::VERTEX_COUNT;
Terrain::Terrain(HeightGenerator heightGenerator) {
this->heightGenerator = heightGenerator;
}
obj::Model Terrain::generateTerrain() {
float vertices[COUNT * 3];
float normals[COUNT * 3];
float textureCoords[COUNT * 2];
int indices[6 * (VERTEX_COUNT - 1) * (VERTEX_COUNT - 1)];
int vertexPointer = 0;
for (int i = 0; i < VERTEX_COUNT; i++) {
for (int j = 0; j < VERTEX_COUNT; j++) {
vertices[vertexPointer * 3] = float(j) / float(VERTEX_COUNT - 1) * SIZE;
float height = getHeight(j, i);
vertices[vertexPointer * 3 + 1] = height;
vertices[vertexPointer * 3 + 2] = 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) * 40;
textureCoords[vertexPointer * 2 + 1] = float(i) / float(VERTEX_COUNT - 1) * 40;
vertexPointer++;
heightTable[j][i] = height;
//std::cout << heightTable[j][i] << std::endl;
}
}
int pointer = 0;
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;
int bottomRight = bottomLeft + 1;
indices[pointer++] = topLeft;
indices[pointer++] = bottomLeft;
indices[pointer++] = topRight;
indices[pointer++] = topRight;
indices[pointer++] = bottomLeft;
indices[pointer++] = bottomRight;
}
}
std::vector<float> vVertices(std::begin(vertices), std::end(vertices));
std::vector<float> vTextures(std::begin(textureCoords), std::end(textureCoords));
std::vector<float> vNormals(std::begin(normals), std::end(normals));
std::map<std::string, std::vector<unsigned int>> faces;
faces[std::string("default")] = std::vector<unsigned int>(std::begin(indices), std::end(indices));
obj::Model model = { vVertices, vTextures, vNormals, faces };
return model;
}
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);
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "HeightGenerator.h"
#include "objload.h"
#include <vector>
class Terrain
{
public:
Terrain() = default;
Terrain(HeightGenerator heightGenerator);
obj::Model generateTerrain();
float heightTable[64][64];
private:
static const float SIZE;
static const int VERTEX_COUNT;
static const int COUNT;
HeightGenerator heightGenerator;
glm::vec3 calculateNormal(int x, int z);
float getHeight(int x, int z);
};

View File

@ -1,4 +1,3 @@
#define STB_IMAGE_IMPLEMENTATION
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
@ -12,30 +11,21 @@
#include "Texture.h"
#include "Camera.h"
#include "SOIL/stb_image_aug.h"
#include "HeightGenerator.h"
#include "Terrain.h"
#include "Engine.h"
#include "Particle.h"
#include "../glm/gtx/matrix_decompose.hpp"
glm::vec4 particlePos;
glm::vec4 particlePosW;
glm::vec4 particlePosS;
Core::Engine engine;
GLuint skyboxProgram, skyboxBuffer;
GLuint bubbleProgram;
GLuint programTexture;
GLuint particlesProgram;
float skyboxBoundary = 500.f;//198.0f;
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 lightDir = glm::normalize(glm::vec3(0.0f, engine.skyboxVerticeParameter, 0.0f));
glm::vec3 cameraPos = glm::vec3(0, 0, 0);
glm::vec3 oldCameraPos = glm::vec3(0, 0, 5);
@ -48,166 +38,35 @@ 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),
});
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;
float moveSpeed = 2.0f;
glm::vec3 nextPosition;
switch (key)
@ -218,14 +77,14 @@ void keyboard(unsigned char key, int x, int y)
nextPosition = cameraPos + (cameraDir * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
addParticleSource(glm::vec3(particlePos.x, particlePos.y, particlePos.z), 1000.0f, 0.6f);
addParticleSource(glm::vec3(particlePosW.x, particlePosW.y, particlePosW.z), 1000.0f, 0.6f);
}
break;
case 's':
nextPosition = cameraPos - (cameraDir * moveSpeed);
if (isInBoundaries(nextPosition)) {
cameraPos = nextPosition;
addParticleSource(glm::vec3(particlePosS.x, particlePosS.y, particlePosS.z), 600.0f, 0.6f);
}
break;
case 'd':
@ -338,40 +197,23 @@ glm::mat4 animationMatrix(float time, glm::vec3 change, std::vector<glm::vec3> k
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);
glClearColor(0.219f, 0.407f, 0.658f, 1.0f);
float time = glutGet(GLUT_ELAPSED_TIME) / 1000.f;
glUseProgram(skyboxProgram);
glUniform1i(glGetUniformLocation(skyboxProgram, "skybox"), 0);
glUseProgram(engine.skyboxShader);
glUniform1i(glGetUniformLocation(engine.skyboxShader, "skybox"), 0);
glm::mat4 transformation = perspectiveMatrix * cameraMatrix;
glUniformMatrix4fv(glGetUniformLocation(skyboxProgram, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation);
glBindVertexArray(skyboxVAO);
glUniformMatrix4fv(glGetUniformLocation(engine.skyboxShader, "projectionViewMatrix"), 1, GL_FALSE, (float*)&transformation);
glBindVertexArray(engine.skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, engine.skyboxTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_BLEND);
@ -379,7 +221,9 @@ void renderScene()
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;
particlePos = submarineModelMatrix * glm::vec4(0, 0.7, 0.3, 1);
particlePosW = submarineModelMatrix * glm::vec4(0, 0.3, 5, 1);
particlePosS = submarineModelMatrix * glm::vec4(0, -0.4, -10, 1);
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);
@ -389,89 +233,60 @@ void renderScene()
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 j = 0; j < 300; j++) {
Core::drawObjectTexture(engine.bubbleContext, animationMatrix(time + j, change0, engine.bubbleArray[j], glm::vec3(0.04f), 0.2f), engine.bubbleTexture, engine.bubbleShader, lightDir, cameraMatrix, perspectiveMatrix);
}
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);
Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change1, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change2, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change3, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
Core::drawObjectTexture(engine.fishContext, animationMatrix(time + 15, change4, fishKeyPoints, glm::vec3(0.25f), 1.f), engine.fishTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
time -= 6;
}
}
//drawObjectTexture(bubbleContext, submarineInitialTransformation, cubemapTexture, bubbleProgram);
drawObjectTexture(submarineContext, submarineModelMatrix, textureSubmarine, programTexture);
handleAllParticleSources(cameraPos, particlesProgram, cameraSide, cameraVertical, cameraMatrix, perspectiveMatrix);
Core::drawObjectTexture(engine.submarineContext, submarineModelMatrix, engine.submarineTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
for (int j = 0; j < 100; j++) {
glm::mat4 objectTransformation;
if (j % 5 == 0) {
objectTransformation = glm::translate(engine.objectArray[j]) * glm::rotate(glm::radians(engine.objectRotation[j]), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(engine.objectSize[j]));
drawObjectTexture(engine.plant1Context, objectTransformation, engine.plant1Texture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
} else if (j % 5 == 1) {
objectTransformation = glm::translate(engine.objectArray[25 + j]) * glm::rotate(glm::radians(engine.objectRotation[j]), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(engine.objectSize[j]));
drawObjectTexture(engine.plant2Context, objectTransformation, engine.plant2Texture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
}
else if (j % 5 == 2) {
objectTransformation = glm::translate(engine.objectArray[50 + j]) * glm::rotate(glm::radians(engine.objectRotation[j]), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(engine.objectSize[j]));
drawObjectTexture(engine.plant3Context, objectTransformation, engine.plant3Texture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
}
else if (j % 5 == 3) {
objectTransformation = glm::translate(engine.objectArray[75 + j]) * glm::rotate(glm::radians(engine.objectRotation[j]), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(engine.objectSize[j]));
drawObjectTexture(engine.coral1Context, objectTransformation, engine.coral1Texture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
}
else if (j % 5 == 4) {
objectTransformation = glm::translate(engine.objectArray[100 + j]) * glm::rotate(glm::radians(engine.objectRotation[j]), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(engine.objectSize[j]));
drawObjectTexture(engine.archContext, objectTransformation, engine.archTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
}
}
for (int i = 0; i < 5; i++) {
glm::mat4 objectTransformation = glm::translate(engine.objectArray[125 + i]) * glm::rotate(glm::radians(0.f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(0.3f));
drawObjectTexture(engine.rocktower1Context, objectTransformation, engine.rocktower1Texture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
}
glm::mat4 terrainTransformation = glm::translate(glm::vec3(200, -185, 200)) * glm::rotate(glm::radians(180.f), glm::vec3(0, 1, 0)) * glm::scale(glm::vec3(8.f));
Core::drawObjectTexture(engine.terrainContext, terrainTransformation, engine.terrainTexture, engine.textureShader, lightDir, cameraMatrix, perspectiveMatrix);
handleAllParticleSources(cameraPos, engine.particleShader, cameraSide, cameraVertical, cameraMatrix, perspectiveMatrix);
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);
@ -491,56 +306,22 @@ void initKeyRotation() {
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()
{
std::default_random_engine gen(HeightGenerator::SEED);
std::uniform_int_distribution<> distr(-engine.skyboxVerticeParameter, engine.skyboxVerticeParameter);
engine.initRandomGenerator(gen, distr);
glEnable(GL_DEPTH_TEST);
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");
particlesProgram = shaderLoader.CreateProgram((char*)"shaders/particles.vert", (char*)"shaders/particles.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");
engine.initShaderPrograms();
engine.initRenderContexts();
engine.loadTextures();
engine.initSkybox();
engine.initBubbles();
engine.generateObjectArray();
engine.generateObjectSize();
engine.generateObjectRotation();
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();
initParticles();
//addParticleSource(glm::vec3(0, 0, 0), 100.0f, 1.5f);
//addParticleSource(glm::vec3(0, 0, 0), 100.0f, 0.3f);
//addParticleSource(glm::vec3(0, 0, 0), 100.0f, 1.5f);
}
void shutdown()
{
shaderLoader.DeleteProgram(programTexture);
shaderLoader.DeleteProgram(skyboxProgram);
shaderLoader.DeleteProgram(bubbleProgram);
shaderLoader.DeleteProgram(particlesProgram);
shutdownParticles();
}
void idle()
@ -566,6 +347,6 @@ int main(int argc, char** argv)
glutSetCursor(GLUT_CURSOR_NONE);
glutMainLoop();
shutdown();
engine.shutdownShaderPrograms();
return 0;
}

140
grafika_projekt/src/mesh.h Normal file
View File

@ -0,0 +1,140 @@
#ifndef MESH_H
#define MESH_H
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "ext.hpp"
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
using namespace std;
struct Vertex {
// position
glm::vec3 Position;
// normal
glm::vec3 Normal;
// texCoords
glm::vec2 TexCoords;
// tangent
glm::vec3 Tangent;
// bitangent
glm::vec3 Bitangent;
};
struct Texture {
unsigned int id;
string type;
string path;
};
class Mesh {
public:
// mesh Data
vector<Vertex> vertices;
vector<unsigned int> indices;
vector<Texture> textures;
glm::mat4 matrix;
unsigned int VAO;
// constructor
Mesh(vector<Vertex> vertices, vector<unsigned int> indices, vector<Texture> textures,glm::mat4 matrix)
{
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
this->matrix = matrix;
// now that we have all the required data, set the vertex buffers and its attribute pointers.
setupMesh();
}
// render the mesh
void Draw(GLuint program)
{
// 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")
number = std::to_string(diffuseNr++);
else if (name == "texture_specular")
number = std::to_string(specularNr++); // transfer unsigned int to stream
else if (name == "texture_normal")
number = std::to_string(normalNr++); // transfer unsigned int to stream
else if (name == "texture_height")
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);
// 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);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// always good practice to set everything back to defaults once configured.
glActiveTexture(GL_TEXTURE0);
}
private:
// render data
unsigned int VBO, EBO;
// initializes all the buffer objects/arrays
void setupMesh()
{
// create buffers/arrays
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
// load data into vertex buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// A great thing about structs is that their memory layout is sequential for all its items.
// The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which
// again translates to 3/2 floats which translates to a byte array.
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
// set the vertex attribute pointers
// vertex Positions
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
// vertex normals
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
// vertex texture coords
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
// vertex tangent
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
// vertex bitangent
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent));
glBindVertexArray(0);
}
};
#endif

250
grafika_projekt/src/model.h Normal file
View File

@ -0,0 +1,250 @@
#pragma once
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "ext.hpp"
#include <iostream>
#include <cmath>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "stb_image.h"
#include "mesh.h"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
unsigned int TextureFromFile(const char* path, const string& directory, bool gamma = false);
class Model
{
public:
// model data
vector<Texture> textures_loaded; // stores all the textures loaded so far, optimization to make sure textures aren't loaded more than once.
vector<Mesh> meshes;
string directory;
bool gammaCorrection;
// constructor, expects a filepath to a 3D model.
Model(string const& path, bool gamma = false) : gammaCorrection(gamma)
{
loadModel(path);
}
// draws the model, and thus all its meshes
void Draw(GLuint shader)
{
for (unsigned int i = 0; i < meshes.size(); i++)
meshes[i].Draw(shader);
}
private:
// loads a model with supported ASSIMP extensions from file and stores the resulting meshes in the meshes vector.
void loadModel(string const& path)
{
// read file via ASSIMP
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
// check for errors
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero
{
cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;
return;
}
// retrieve the directory path of the filepath
directory = path.substr(0, path.find_last_of('/'));
// process ASSIMP's root node recursively
processNode(scene->mRootNode, scene,glm::mat4());
}
// processes a node in a recursive fashion. Processes each individual mesh located at the node and repeats this process on its children nodes (if any).
void processNode(aiNode* node, const aiScene* scene,glm::mat4 matrix)
{
glm::mat4 outMatrix = matrix * mat4_cast(node->mTransformation);
// process each mesh located at the current node
for (unsigned int i = 0; i < node->mNumMeshes; i++)
{
// the node object only contains indices to index the actual objects in the scene.
// the scene contains all the data, node is just to keep stuff organized (like relations between nodes).
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(processMesh(mesh, scene, outMatrix));
}
// after we've processed all of the meshes (if any) we then recursively process each of the children nodes
for (unsigned int i = 0; i < node->mNumChildren; i++)
{
processNode(node->mChildren[i], scene, outMatrix);
}
}
Mesh processMesh(aiMesh* mesh, const aiScene* scene, glm::mat4 matrix)
{
// data to fill
vector<Vertex> vertices;
vector<unsigned int> indices;
vector<Texture> textures;
// walk through each of the mesh's vertices
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
{
Vertex vertex;
glm::vec3 vector; // we declare a placeholder vector since assimp uses its own vector class that doesn't directly convert to glm's vec3 class so we transfer the data to this placeholder glm::vec3 first.
// positions
vector.x = mesh->mVertices[i].x;
vector.y = mesh->mVertices[i].y;
vector.z = mesh->mVertices[i].z;
vertex.Position = vector;
// normals
if (mesh->HasNormals())
{
vector.x = mesh->mNormals[i].x;
vector.y = mesh->mNormals[i].y;
vector.z = mesh->mNormals[i].z;
vertex.Normal = vector;
}
// texture coordinates
if (mesh->mTextureCoords[0]) // does the mesh contain texture coordinates?
{
glm::vec2 vec;
// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
vec.x = mesh->mTextureCoords[0][i].x;
vec.y = mesh->mTextureCoords[0][i].y;
vertex.TexCoords = vec;
// tangent
vector.x = mesh->mTangents[i].x;
vector.y = mesh->mTangents[i].y;
vector.z = mesh->mTangents[i].z;
vertex.Tangent = vector;
// bitangent
vector.x = mesh->mBitangents[i].x;
vector.y = mesh->mBitangents[i].y;
vector.z = mesh->mBitangents[i].z;
vertex.Bitangent = vector;
}
else
vertex.TexCoords = glm::vec2(0.0f, 0.0f);
vertices.push_back(vertex);
}
// now wak through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices.
for (unsigned int i = 0; i < mesh->mNumFaces; i++)
{
aiFace face = mesh->mFaces[i];
// retrieve all indices of the face and store them in the indices vector
for (unsigned int j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}
// process materials
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
// we assume a convention for sampler names in the shaders. Each diffuse texture should be named
// as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER.
// Same applies to other texture as the following list summarizes:
// diffuse: texture_diffuseN
// specular: texture_specularN
// normal: texture_normalN
// 1. diffuse maps
vector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
// 2. specular maps
vector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
// 3. normal maps
std::vector<Texture> normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal");
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
// 4. height maps
std::vector<Texture> heightMaps = loadMaterialTextures(material, aiTextureType_AMBIENT, "texture_height");
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
// return a mesh object created from the extracted mesh data
return Mesh(vertices, indices, textures, matrix);
}
// checks all material textures of a given type and loads the textures if they're not loaded yet.
// the required info is returned as a Texture struct.
vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName)
{
vector<Texture> textures;
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++)
{
aiString str;
mat->GetTexture(type, i, &str);
// check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
bool skip = false;
for (unsigned int j = 0; j < textures_loaded.size(); j++)
{
if (std::strcmp(textures_loaded[j].path.data(), str.C_Str()) == 0)
{
textures.push_back(textures_loaded[j]);
skip = true; // a texture with the same filepath has already been loaded, continue to next one. (optimization)
break;
}
}
if (!skip)
{ // if texture hasn't been loaded already, load it
Texture texture;
texture.id = TextureFromFile(str.C_Str(), this->directory);
texture.type = typeName;
texture.path = str.C_Str();
textures.push_back(texture);
textures_loaded.push_back(texture); // store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
}
}
return textures;
}
};
unsigned int TextureFromFile(const char* path, const string& directory, bool gamma)
{
string filename = string(path);
filename = directory + '/' + filename;
unsigned int textureID;
glGenTextures(1, &textureID);
int width, height, nrComponents;
unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
if (data)
{
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
{
std::cout << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data);
}
return textureID;
}

View File

@ -40,7 +40,7 @@ struct Model {
std::vector<float> texCoord; //< 2 * N entries
std::vector<float> normal; //< 3 * N entries
std::map<std::string, std::vector<unsigned short> > faces; //< assume triangels and uniform indexing
std::map<std::string, std::vector<unsigned int> > faces; //< assume triangels and uniform indexing
};
struct ObjModel {
@ -221,10 +221,10 @@ Model convertToModel( const ObjModel & obj ) {
for(std::map<std::string, ObjModel::FaceList>::const_iterator g = obj.faces.begin(); g != obj.faces.end(); ++g){
const std::string & name = g->first;
const ObjModel::FaceList & fl = g->second;
std::vector<unsigned short> & v = model.faces[g->first];
std::vector<unsigned int> & v = model.faces[g->first];
v.reserve(fl.first.size());
for(std::vector<ObjModel::FaceVertex>::const_iterator f = fl.first.begin(); f != fl.first.end(); ++f){
const unsigned short index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
const unsigned int index = std::distance(unique.begin(), std::lower_bound(unique.begin(), unique.end(), *f));
v.push_back(index);
}
}
@ -276,7 +276,7 @@ std::ostream & operator<<( std::ostream & out, const Model & m ){
}
if(!m.faces.empty()){
out << "faces\t";
for(std::map<std::string, std::vector<unsigned short> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
for(std::map<std::string, std::vector<unsigned int> >::const_iterator g = m.faces.begin(); g != m.faces.end(); ++g){
out << g->first << " ";
}
out << "\n";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 891 KiB