|
@@ -1,12 +1,13 @@
|
|
|
#include <GL/glew.h>
|
|
|
#include <GLFW/glfw3.h>
|
|
|
+#include <math.h>
|
|
|
#include <stdbool.h>
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
-#define WIDTH 400
|
|
|
-#define HEIGHT 400
|
|
|
+#define WIDTH 800
|
|
|
+#define HEIGHT 800
|
|
|
|
|
|
static const GLchar* vertexShaderCode = "#version 430\n"
|
|
|
"layout(location = 0) in vec2 pos;"
|
|
@@ -37,11 +38,11 @@ static const GLchar* fragmentShaderCode =
|
|
|
""
|
|
|
"void main(void) {"
|
|
|
" float f = texture(samp, varTex).r;"
|
|
|
- " //color = vec4(f, f, f, 1.0);\n"
|
|
|
+ " color = vec4(f, f, f, 1.0);\n"
|
|
|
" //color = heightColors[min(int(5 * f), 4)];\n"
|
|
|
- " int a = int(min(floor(5 * f), 4));"
|
|
|
- " int b = int(min(ceil(5 * f), 4));"
|
|
|
- " color = mix(heightColors[a], heightColors[b], 5 * f - a);\n"
|
|
|
+ " //int a = int(min(floor(5 * f), 4));"
|
|
|
+ " //int b = int(min(ceil(5 * f), 4));"
|
|
|
+ " //color = mix(heightColors[a], heightColors[b], 5 * f - a);\n"
|
|
|
"}";
|
|
|
|
|
|
static GLFWwindow* window = NULL;
|
|
@@ -52,28 +53,49 @@ static GLuint vertexArray = 0;
|
|
|
static GLuint vertexBuffer = 0;
|
|
|
static GLuint texture = 0;
|
|
|
static GLfloat noise[WIDTH][HEIGHT];
|
|
|
-static unsigned long long seed = 0;
|
|
|
+static unsigned int seed = 1;
|
|
|
|
|
|
-static float nextFloat() {
|
|
|
- seed = seed * 534492383lu + 31;
|
|
|
- return (unsigned int)(seed >> 16) / (float)(-1u);
|
|
|
+static float nextSeededFloat(unsigned int x, unsigned int y) {
|
|
|
+ unsigned int s = y + ((x + y) * (x + y + 1)) / 2;
|
|
|
+ s ^= s * (x + seed) * 534492383u;
|
|
|
+ s ^= s * (y + seed) * 23537u;
|
|
|
+ return s / (float)(-1u);
|
|
|
}
|
|
|
|
|
|
-static void smooth(int size) {
|
|
|
- float divider = 1.0f / (size * size);
|
|
|
- static GLfloat newNoise[WIDTH][HEIGHT];
|
|
|
- for(int x = 0; x < WIDTH; x++) {
|
|
|
- for(int y = 0; y < HEIGHT; y++) {
|
|
|
- float sum = 0.0f;
|
|
|
- for(int mx = 0; mx < size; mx++) {
|
|
|
- for(int my = 0; my < size; my++) {
|
|
|
- sum += noise[(x + mx) % WIDTH][(y + my) % HEIGHT];
|
|
|
- }
|
|
|
- }
|
|
|
- newNoise[x][y] = sum * divider;
|
|
|
- }
|
|
|
- }
|
|
|
- memcpy(noise, newNoise, sizeof(newNoise));
|
|
|
+static float interpolate(float a, float b, float f) {
|
|
|
+ return (b - a) * (3.0 - f * 2.0) * f * f + a;
|
|
|
+}
|
|
|
+
|
|
|
+static float dot(int ix, int iy, float x, float y, float zoom) {
|
|
|
+ float f =
|
|
|
+ nextSeededFloat(ix % (int)(WIDTH / zoom), iy % (int)(HEIGHT / zoom)) *
|
|
|
+ M_PI * 2.0f;
|
|
|
+ return (x - ix) * cosf(f) + (y - iy) * sinf(f);
|
|
|
+}
|
|
|
+
|
|
|
+float perlin(float x, float y, float zoom) {
|
|
|
+ x /= zoom;
|
|
|
+ y /= zoom;
|
|
|
+ int ix = x;
|
|
|
+ int iy = y;
|
|
|
+ int ix1 = ix + 1;
|
|
|
+ int iy1 = iy + 1;
|
|
|
+ float sx = x - ix;
|
|
|
+ return interpolate(
|
|
|
+ interpolate(dot(ix, iy, x, y, zoom), dot(ix1, iy, x, y, zoom), sx),
|
|
|
+ interpolate(dot(ix, iy1, x, y, zoom), dot(ix1, iy1, x, y, zoom), sx),
|
|
|
+ y - iy);
|
|
|
+}
|
|
|
+
|
|
|
+float transform(float x, float y, float zoom) {
|
|
|
+ return (perlin(x, y, zoom) + 1.0f) * 0.5f;
|
|
|
+}
|
|
|
+
|
|
|
+float turbulence(int x, int y) {
|
|
|
+ float sum = transform(x, y, 80.0f);
|
|
|
+ sum += transform(x, y, 200.0f);
|
|
|
+ sum += transform(x, y, 400.0f);
|
|
|
+ return sum / 3.0f;
|
|
|
}
|
|
|
|
|
|
static void normalize() {
|
|
@@ -96,19 +118,12 @@ static void normalize() {
|
|
|
static void generateNoise() {
|
|
|
for(int x = 0; x < WIDTH; x++) {
|
|
|
for(int y = 0; y < HEIGHT; y++) {
|
|
|
- noise[x][y] = nextFloat();
|
|
|
+ noise[x][y] = turbulence(x, y);
|
|
|
}
|
|
|
}
|
|
|
- smooth(2);
|
|
|
- smooth(4);
|
|
|
- smooth(8);
|
|
|
- smooth(16);
|
|
|
- smooth(32);
|
|
|
- smooth(64);
|
|
|
normalize();
|
|
|
|
|
|
(void)normalize;
|
|
|
- (void)smooth;
|
|
|
}
|
|
|
|
|
|
static bool checkShaderError(GLuint shader, const char* name) {
|
|
@@ -177,7 +192,7 @@ static void initTexture() {
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
generateNoise();
|
|
|
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, WIDTH, HEIGHT, 0, GL_RED, GL_FLOAT,
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, HEIGHT, WIDTH, 0, GL_RED, GL_FLOAT,
|
|
|
noise);
|
|
|
}
|
|
|
|
|
@@ -222,10 +237,18 @@ static void start() {
|
|
|
if(createWindow() || init()) {
|
|
|
return;
|
|
|
}
|
|
|
+ int i = 0;
|
|
|
while(!glfwWindowShouldClose(window)) {
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture);
|
|
|
+ if(i++ == 100) {
|
|
|
+ seed++;
|
|
|
+ i = 0;
|
|
|
+ generateNoise();
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, HEIGHT, WIDTH, 0, GL_RED,
|
|
|
+ GL_FLOAT, noise);
|
|
|
+ }
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
glBindVertexArray(vertexArray);
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|