feat: add terrain generation using perlin noise #12
@ -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);
|
@ -142,6 +142,8 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\RawModel.cpp" />
|
||||
<ClCompile Include="src\HeightGenerator.cpp" />
|
||||
<ClCompile Include="src\Camera.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
<ClCompile Include="src\Render_Utils.cpp" />
|
||||
@ -151,8 +153,11 @@
|
||||
<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\RawModel.h" />
|
||||
<ClInclude Include="src\HeightGenerator.h" />
|
||||
<ClInclude Include="src\Camera.h" />
|
||||
<ClInclude Include="src\objload.h" />
|
||||
<ClInclude Include="src\Render_Utils.h" />
|
||||
@ -164,7 +169,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" />
|
||||
|
@ -42,6 +42,15 @@
|
||||
<ClCompile Include="src\Render_Utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\HeightGenerator.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Terrain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\RawModel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\Shader_Loader.h">
|
||||
@ -77,7 +86,13 @@
|
||||
<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\RawModel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
61
grafika_projekt/src/HeightGenerator.cpp
Normal file
61
grafika_projekt/src/HeightGenerator.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include "HeightGenerator.h"
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
|
||||
# define MY_PI 3.14159265358979323846
|
||||
|
||||
std::random_device rd; // obtain a random number from hardware
|
||||
|
||||
const int HeightGenerator::SEED = rd();
|
||||
const float HeightGenerator::AMPLITUDE = 75.f;
|
||||
const int HeightGenerator::OCTAVES = 3;
|
||||
const float HeightGenerator::ROUGHNESS = 0.3f;
|
||||
const int HeightGenerator::xOffset = 0;
|
||||
const int HeightGenerator::zOffset = 0;
|
||||
|
||||
float HeightGenerator::generateHeight(int x, int z) {
|
||||
float total = 0;
|
||||
float d = pow(2, OCTAVES - 1);
|
||||
for (int i = 0; i < OCTAVES; i++) {
|
||||
float freq = pow(2, i) / d;
|
||||
float amp = pow(ROUGHNESS, i) * AMPLITUDE;
|
||||
total += getInterpolatedNoise((x + xOffset) * freq, (z + zOffset) * 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 - f) + b * f;
|
||||
}
|
||||
|
||||
float HeightGenerator::getSmoothNoise(int x, int z) {
|
||||
float corners = (getNoise(x - 1, z - 1) + getNoise(x + 1, z - 1) + getNoise(x - 1, z + 1) + getNoise(x + 1, z + 1)) / 16.f;
|
||||
float sides = (getNoise(x - 1, z) + getNoise(x + 1, z) + getNoise(x, z - 1) + getNoise(x, z + 1)) / 8.f;
|
||||
float center = getNoise(x, z) / 4.f;
|
||||
return corners + sides + center;
|
||||
}
|
||||
|
||||
float HeightGenerator::getNoise(int x, int z) {
|
||||
std::mt19937 gen(SEED + x * 49632 + z * 325176);
|
||||
std::uniform_real_distribution<> distr(0, 100000000);
|
||||
|
||||
return distr(gen) * 2.f - 1.f;
|
||||
}
|
18
grafika_projekt/src/HeightGenerator.h
Normal file
18
grafika_projekt/src/HeightGenerator.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
class HeightGenerator
|
||||
{
|
||||
public:
|
||||
float generateHeight(int x, int z);
|
||||
static const int SEED;
|
||||
private:
|
||||
static const float AMPLITUDE;
|
||||
static const int OCTAVES;
|
||||
static const float ROUGHNESS;
|
||||
static const int xOffset;
|
||||
static const int zOffset;
|
||||
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);
|
||||
};
|
6
grafika_projekt/src/RawModel.cpp
Normal file
6
grafika_projekt/src/RawModel.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "RawModel.h"
|
||||
|
||||
RawModel::RawModel(int vaoID, int vertexCount) {
|
||||
this->vaoID = vaoID;
|
||||
this->vertexCount = vertexCount;
|
||||
}
|
11
grafika_projekt/src/RawModel.h
Normal file
11
grafika_projekt/src/RawModel.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
class RawModel
|
||||
{
|
||||
public:
|
||||
RawModel() = default;
|
||||
RawModel(int vaoID, int vertexCount);
|
||||
private:
|
||||
int vaoID;
|
||||
int vertexCount;
|
||||
};
|
||||
|
73
grafika_projekt/src/Terrain.cpp
Normal file
73
grafika_projekt/src/Terrain.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include "Terrain.h"
|
||||
#include "glew.h"
|
||||
#include "freeglut.h"
|
||||
|
||||
|
||||
const float Terrain::SIZE = 800.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) {
|
||||
x = gridX * SIZE;
|
||||
z = gridZ * SIZE;
|
||||
texture = textureID;
|
||||
model = generateTerrain();
|
||||
}
|
||||
|
||||
RawModel 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;
|
||||
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;
|
||||
vertexPointer++;
|
||||
}
|
||||
}
|
||||
int pointer = 0;
|
||||
for (int gz = 0; gz < VERTEX_COUNT; gz++) {
|
||||
for (int gx = 0; gx < VERTEX_COUNT; 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;
|
||||
}
|
||||
}
|
||||
unsigned int vaoID;
|
||||
glGenVertexArrays(1, &vaoID);
|
||||
glBindVertexArray(vaoID);
|
||||
unsigned int vboID;
|
||||
glGenBuffers(1, &vboID);
|
||||
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[]) {
|
||||
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);
|
||||
}
|
19
grafika_projekt/src/Terrain.h
Normal file
19
grafika_projekt/src/Terrain.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "RawModel.h"
|
||||
|
||||
class Terrain
|
||||
{
|
||||
public:
|
||||
Terrain() = default;
|
||||
Terrain(int gridX, int gridZ, GLuint textureID);
|
||||
private:
|
||||
static const float SIZE;
|
||||
static const int VERTEX_COUNT;
|
||||
static const int COUNT;
|
||||
float x;
|
||||
float z;
|
||||
GLuint texture;
|
||||
RawModel model;
|
||||
RawModel generateTerrain();
|
||||
void storeDataInAttributeList(int attributeNumber, int coordinateSize, float data[]);
|
||||
};
|
@ -12,6 +12,8 @@
|
||||
#include "Texture.h"
|
||||
#include "Camera.h"
|
||||
#include "SOIL/stb_image_aug.h"
|
||||
#include "HeightGenerator.h"
|
||||
#include "Terrain.h"
|
||||
|
||||
GLuint skyboxProgram, skyboxBuffer;
|
||||
GLuint bubbleProgram;
|
||||
@ -175,9 +177,7 @@ bool isInBoundaries(glm::vec3 nextPosition) {
|
||||
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::default_random_engine gen(HeightGenerator::SEED); // seed the generator
|
||||
std::uniform_int_distribution<> distr(-skyboxVerticeParameter, skyboxVerticeParameter); // define the range
|
||||
|
||||
std::vector<glm::vec3> genBubbleKeyPoints() {
|
||||
@ -514,6 +514,9 @@ void init()
|
||||
initCube();
|
||||
initSkybox();
|
||||
|
||||
//GLuint textureID = Core::LoadTexture('textura_terrain');
|
||||
//Terrain terrain = new Terrain(0, 0, textureID);
|
||||
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
@ -521,7 +524,6 @@ void shutdown()
|
||||
shaderLoader.DeleteProgram(programTexture);
|
||||
shaderLoader.DeleteProgram(skyboxProgram);
|
||||
shaderLoader.DeleteProgram(bubbleProgram);
|
||||
|
||||
}
|
||||
|
||||
void idle()
|
||||
|
Loading…
Reference in New Issue
Block a user