feat: add terrain generation using perlin noise #12

Merged
s452622 merged 11 commits from terrain-generation-second-approach into master 2022-01-25 12:18:30 +01:00
11 changed files with 36 additions and 265 deletions
Showing only changes of commit 7a2a862a94 - Show all commits

View File

@ -142,7 +142,6 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\RawModel.cpp" />
<ClCompile Include="src\HeightGenerator.cpp" /> <ClCompile Include="src\HeightGenerator.cpp" />
<ClCompile Include="src\Camera.cpp" /> <ClCompile Include="src\Camera.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
@ -154,10 +153,8 @@
<ClCompile Include="src\SOIL\stb_image_aug.c" /> <ClCompile Include="src\SOIL\stb_image_aug.c" />
<ClCompile Include="src\Texture.cpp" /> <ClCompile Include="src\Texture.cpp" />
<ClCompile Include="src\Terrain.cpp" /> <ClCompile Include="src\Terrain.cpp" />
<ClCompile Include="src\TerrainRenderer.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\RawModel.h" />
<ClInclude Include="src\HeightGenerator.h" /> <ClInclude Include="src\HeightGenerator.h" />
<ClInclude Include="src\Camera.h" /> <ClInclude Include="src\Camera.h" />
<ClInclude Include="src\objload.h" /> <ClInclude Include="src\objload.h" />
@ -171,7 +168,6 @@
<ClInclude Include="src\SOIL\stb_image_aug.h" /> <ClInclude Include="src\SOIL\stb_image_aug.h" />
<ClInclude Include="src\Texture.h" /> <ClInclude Include="src\Texture.h" />
<ClInclude Include="src\Terrain.h" /> <ClInclude Include="src\Terrain.h" />
<ClInclude Include="src\TerrainRenderer.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="assimp-vc141-mt.dll" /> <None Include="assimp-vc141-mt.dll" />

View File

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

View File

@ -1,36 +0,0 @@
#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

@ -1,28 +0,0 @@
#version 400 core
layout(location = 3) in vec3 position;
layout(location = 4) in vec2 textureCoordinates;
layout(location = 5) 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

@ -1,14 +0,0 @@
#include "RawModel.h"
RawModel::RawModel(int vaoID, int vertexCount) {
this->vaoID = vaoID;
this->vertexCount = vertexCount;
}
int RawModel::getVertexCount() {
return vertexCount;
}
int RawModel::getVaoID() {
return vaoID;
}

View File

@ -1,13 +0,0 @@
#pragma once
class RawModel
{
public:
RawModel() = default;
RawModel(int vaoID, int vertexCount);
int getVertexCount();
int getVaoID();
private:
int vaoID;
int vertexCount;
};

View File

@ -1,22 +1,18 @@
#include "Terrain.h" #include "Terrain.h"
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
const float Terrain::SIZE = 100.f; const float Terrain::SIZE = 100.f;
const int Terrain::VERTEX_COUNT = 64; const int Terrain::VERTEX_COUNT = 32;
const int Terrain::COUNT = Terrain::VERTEX_COUNT * Terrain::VERTEX_COUNT; const int Terrain::COUNT = Terrain::VERTEX_COUNT * Terrain::VERTEX_COUNT;
Terrain::Terrain(int gridX, int gridZ, GLuint textureID, HeightGenerator heightGenerator) { Terrain::Terrain(int gridX, int gridZ, HeightGenerator heightGenerator) {
x = gridX * SIZE; x = gridX * SIZE;
z = gridZ * SIZE; z = gridZ * SIZE;
texture = textureID;
model = generateTerrain();
this->heightGenerator = heightGenerator; this->heightGenerator = heightGenerator;
} }
RawModel Terrain::generateTerrain() { obj::Model Terrain::generateTerrain() {
float vertices[COUNT * 3]; float vertices[COUNT * 3];
float normals[COUNT * 3]; float normals[COUNT * 3];
float textureCoords[COUNT * 2]; float textureCoords[COUNT * 2];
@ -31,8 +27,8 @@ RawModel Terrain::generateTerrain() {
normals[vertexPointer * 3] = normal.x; normals[vertexPointer * 3] = normal.x;
normals[vertexPointer * 3 + 1] = normal.y; normals[vertexPointer * 3 + 1] = normal.y;
normals[vertexPointer * 3 + 2] = normal.z; normals[vertexPointer * 3 + 2] = normal.z;
textureCoords[vertexPointer * 2] = float(j) / float(VERTEX_COUNT - 1);// *SIZE; textureCoords[vertexPointer * 2] = float(j) / float(VERTEX_COUNT - 1);
textureCoords[vertexPointer * 2 + 1] = float(i) / float(VERTEX_COUNT - 1);// *SIZE; textureCoords[vertexPointer * 2 + 1] = float(i) / float(VERTEX_COUNT - 1);
vertexPointer++; vertexPointer++;
} }
} }
@ -51,37 +47,16 @@ RawModel Terrain::generateTerrain() {
indices[pointer++] = bottomRight; indices[pointer++] = bottomRight;
} }
} }
unsigned int vaoID; std::vector<float> vVertices(std::begin(vertices), std::end(vertices));
glGenVertexArrays(1, &vaoID); std::vector<float> vTextures(std::begin(textureCoords), std::end(textureCoords));
glBindVertexArray(vaoID); std::vector<float> vNormals(std::begin(normals), std::end(normals));
unsigned int vboID; std::map<std::string, std::vector<unsigned short>> faces;
glGenBuffers(1, &vboID); faces[std::string("default")] = std::vector<unsigned short>(std::begin(indices), std::end(indices));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices, GL_STATIC_DRAW);
storeDataInAttributeList(0, 3, vertices);
storeDataInAttributeList(1, 2, textureCoords);
storeDataInAttributeList(2, 3, normals);
glBindVertexArray(0);
return RawModel(vaoID, sizeof indices / sizeof indices[0]);
}
void Terrain::storeDataInAttributeList(int attributeNumber, int coordinateSize, float data[]) { obj::Model model = { vVertices, vTextures, vNormals, faces };
unsigned int vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), &data, GL_STATIC_DRAW);
glVertexAttribPointer(attributeNumber, coordinateSize, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
RawModel Terrain::getModel() {
return model; return model;
} }
GLuint Terrain::getTexture() {
return texture;
}
glm::vec3 Terrain::calculateNormal(int x, int z) { glm::vec3 Terrain::calculateNormal(int x, int z) {
float heightL = getHeight(x - 1, z); float heightL = getHeight(x - 1, z);
float heightR = getHeight(x + 1, z); float heightR = getHeight(x + 1, z);

View File

@ -1,17 +1,17 @@
#pragma once #pragma once
#include "RawModel.h"
#include "glew.h" #include "glew.h"
#include "freeglut.h" #include "freeglut.h"
#include "glm.hpp" #include "glm.hpp"
#include "HeightGenerator.h" #include "HeightGenerator.h"
#include "objload.h"
#include <vector>
class Terrain class Terrain
{ {
public: public:
Terrain() = default; Terrain() = default;
Terrain(int gridX, int gridZ, GLuint textureID, HeightGenerator heightGenerator); Terrain(int gridX, int gridZ, HeightGenerator heightGenerator);
RawModel getModel(); obj::Model generateTerrain();
GLuint getTexture();
int getX(); int getX();
int getZ(); int getZ();
@ -22,10 +22,6 @@ private:
float x; float x;
float z; float z;
HeightGenerator heightGenerator; HeightGenerator heightGenerator;
GLuint texture;
RawModel model;
RawModel generateTerrain();
void storeDataInAttributeList(int attributeNumber, int coordinateSize, float data[]);
glm::vec3 calculateNormal(int x, int z); glm::vec3 calculateNormal(int x, int z);
float getHeight(int x, int z); float getHeight(int x, int z);
}; };

View File

@ -1,60 +0,0 @@
#include "TerrainRenderer.h"
#include "glew.h"
#include "freeglut.h"
#include "glm.hpp"
#include "iostream"
#include "Texture.h"
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);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindVertexArray(0);
}
void TerrainRenderer::initShader() {
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);
}
void TerrainRenderer::prepareTerrain() {
RawModel rawModel = terrain.getModel();
glBindVertexArray(rawModel.getVaoID());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
GLuint texture = terrain.getTexture();
Core::SetActiveTexture(texture, "modelTexture", terrainProgram, 0);
}

View File

@ -1,36 +0,0 @@
#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,7 +14,6 @@
#include "SOIL/stb_image_aug.h" #include "SOIL/stb_image_aug.h"
#include "HeightGenerator.h" #include "HeightGenerator.h"
#include "Terrain.h" #include "Terrain.h"
#include "TerrainRenderer.h"
GLuint skyboxProgram, skyboxBuffer; GLuint skyboxProgram, skyboxBuffer;
GLuint bubbleProgram; GLuint bubbleProgram;
@ -51,8 +50,9 @@ Core::Shader_Loader shaderLoader;
Core::RenderContext submarineContext; Core::RenderContext submarineContext;
Core::RenderContext fishContext; Core::RenderContext fishContext;
Core::RenderContext bubbleContext; Core::RenderContext bubbleContext;
Core::RenderContext terrainContext;
GLuint textureID; GLuint textureTerrain;
HeightGenerator heightGenerator; HeightGenerator heightGenerator;
std::vector<glm::vec3> fishKeyPoints({ std::vector<glm::vec3> fishKeyPoints({
@ -371,18 +371,18 @@ void renderScene()
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glUseProgram(terrainProgram);
glm::mat4 terrainTransformation = glm::translate(glm::vec3(0, 0, 0)) * glm::rotate(glm::radians(180.f), glm::vec3(5, 5, 5));
TerrainRenderer terrainRenderer(terrainProgram, perspectiveMatrix, terrain, terrainTransformation, cameraMatrix, lightDir, 0.5f, 0.5f);
terrainRenderer.render();
glUseProgram(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;
///
drawObjectTexture(terrainContext, glm::translate(glm::vec3(1, 1, 1)), textureTerrain, programTexture);
///
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::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 change1 = glm::vec3(0, 3, 0);
@ -393,7 +393,7 @@ void renderScene()
glm::vec3 change0 = glm::vec3(0, 0, 0); glm::vec3 change0 = glm::vec3(0, 0, 0);
for (int j = 0; j < 100; j++) { for (int j = 0; j < 100; j++) {
drawObjectTexture(bubbleContext, animationMatrix(time + j, change0, bubbleArray[j], glm::vec3(0.04f), 0.2f), cubemapTexture, bubbleProgram); drawObjectTexture(bubbleContext, animationMatrix(time + j, change0, bubbleArray[j], glm::vec3(0.04f), 0.2f), textureBubble, bubbleProgram);
} }
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@ -512,7 +512,6 @@ void init()
programTexture = shaderLoader.CreateProgram((char*)"shaders/shader_tex.vert", (char*)"shaders/shader_tex.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"); skyboxProgram = shaderLoader.CreateProgram((char*)"shaders/skybox.vert", (char*)"shaders/skybox.frag");
bubbleProgram = shaderLoader.CreateProgram((char*)"shaders/bubble.vert", (char*)"shaders/bubble.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(); cubemapTexture = loadCubemap();
@ -522,6 +521,15 @@ void init()
loadModelToContext("models/fish.obj", fishContext); loadModelToContext("models/fish.obj", fishContext);
textureFish = Core::LoadTexture("textures/fish.png"); textureFish = Core::LoadTexture("textures/fish.png");
textureTerrain = Core::LoadTexture("textures/terrain.png");
terrain = Terrain(0, 0, heightGenerator);
obj::Model model = terrain.generateTerrain();
terrainContext.initFromOBJ(model);
initKeyRotation(); initKeyRotation();
loadModelToContext("models/submarine.obj", submarineContext); loadModelToContext("models/submarine.obj", submarineContext);
textureSubmarine = Core::LoadTexture("textures/submarine.png"); textureSubmarine = Core::LoadTexture("textures/submarine.png");
@ -530,11 +538,6 @@ void init()
generateBubbleArray(); generateBubbleArray();
initCube(); initCube();
initSkybox(); initSkybox();
textureID = Core::LoadTexture("textures/terrain.png");
terrain = Terrain(0, 0, textureID, heightGenerator);
} }
void shutdown() void shutdown()