#include
"grid.h"
using namespace std;
Grid::Grid(unsigned int size,float minval,float maxval) {
const float w = maxval-minval;
const float h = w;
const float stepW = w/(float)size;
const float stepH = h/(float)size;
const float startx = minval;
const float starty = minval;
for(unsigned int i=0;i<size;++i) {
for(unsigned int j=0;j<size;++j) {
const float currentx =
startx+stepW*(float)j;
const float currenty =
starty+stepH*(float)i;
_vertices.push_back(currentx);
_vertices.push_back(currenty);
_vertices.push_back(0.0f);
if(i>0 && j>0) {
int i1 = i*size+j;
int i2 = (i-1)*size+j;
int i3 = (i-1)*size+j-1;
int i4 = i*size+j-1;
_faces.push_back(i1);
_faces.push_back(i2);
_faces.push_back(i3);
_faces.push_back(i3);
_faces.push_back(i4);
_faces.push_back(i1);
}
}
}
_nbVertices = _vertices.size()/3;
_nbFaces = _faces.size()/3;
}
Grid::~Grid() {
_vertices.clear();
_faces.clear();
}
VAO
creation/suppression
void Viewer::createVAO() {
//the variable _grid should be an instance of Grid
//the .h file should contain the following VAO/buffer ids
//GLuint _vaoTerrain;
//GLuint _vaoQuad;
//GLuint _terrain[2];
//GLuint _quad;
const GLfloat quadData[] = {
-1.0f,-1.0f,0.0f, 1.0f,-1.0f,0.0f, -1.0f,1.0f,0.0f,
-1.0f,1.0f,0.0f, 1.0f,-1.0f,0.0f, 1.0f,1.0f,0.0f };
glGenBuffers(2,_terrain);
glGenBuffers(1,&_quad);
glGenVertexArrays(1,&_vaoTerrain);
glGenVertexArrays(1,&_vaoQuad);
// create the VBO associated with the grid (the terrain)
glBindVertexArray(_vaoTerrain);
glBindBuffer(GL_ARRAY_BUFFER,_terrain[0]); // vertices
glBufferData(GL_ARRAY_BUFFER,_grid->nbVertices()*3*sizeof(float),_grid->vertices(),GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void *)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,_terrain[1]); // indices
glBufferData(GL_ELEMENT_ARRAY_BUFFER,_grid->nbFaces()*3*sizeof(int),_grid->faces(),GL_STATIC_DRAW);
// create the VBO associated with the screen quad
glBindVertexArray(_vaoQuad);
glBindBuffer(GL_ARRAY_BUFFER,_quad); // vertices
glBufferData(GL_ARRAY_BUFFER,
sizeof(quadData),quadData,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void *)0);
glEnableVertexAttribArray(0);
}
void Viewer::deleteVAO() {
glDeleteBuffers(2,_terrain);
glDeleteBuffers(1,&_quad);
glDeleteVertexArrays(1,&_vaoTerrain);
glDeleteVertexArrays(1,&_vaoQuad);
}
noise.vert
#version 330
// input attributes
layout(location = 0) in vec3 position;
out vec2 pos;
void main() {
// no need for any particular transformation (Identity matrices)
pos = position.xy*0.5+0.5;
gl_Position = vec4(position,1);
}
noise.frag
#version 330
in vec2 pos;
out vec4 outBuffer;
vec2 hash(vec2 p) {
p = vec2( dot(p,vec2(127.1,311.7)),
dot(p,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}
float gnoise(in vec2 p) {
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( dot( hash( i + vec2(0.0,0.0) ), f -
vec2(0.0,0.0) ),
dot( hash( i +
vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
mix( dot( hash( i +
vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
dot( hash( i +
vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}
float pnoise(in vec2 p,in float amplitude,in float frequency,in float
persistence, in int nboctaves) {
float a = amplitude;
float f = frequency;
float n = 0.0;
for(int i=0;i<nboctaves;++i) {
n = n+a*gnoise(p*f);
f = f*2.;
a = a*persistence;
}
return n;
}
void main() {
vec3 motion = vec3(0.); // could be controlled via a global
uniform variable
float p = pnoise(pos+motion.xy,2.0,4.0,0.5,10)+motion.z;
outBuffer = vec4(p*0.5+0.5);
}
normal.vert
layout(location = 0) in vec3 position;
out
vec2 texcoord;
void
main() {
gl_Position = vec4(vertex,0,1);
texcoord = position.xy*0.5+0.5;
}
normal.frag
out vec4 outBuffer;
uniform sampler2D heightmap;
in
vec2 texcoord;
float
value(in vec4 c) {
// gradient of what:
return c.x;// the height is stored in all channels (take the first
one)
}
void
main() {
vec2 ps = 1./vec2(textureSize(heightmap,0));
vec2 g = vec2( value(texture(heightmap,texcoord+vec2(ps.x,0.))) -
value(texture(heightmap,texcoord-vec2(ps.x,0.))),
value(texture(heightmap,texcoord+vec2(0.,ps.y))) -
value(texture(heightmap,texcoord-vec2(0.,ps.y))))/2.;
float scale = 100.;
vec3 n1 = vec3(1.,0.,g.x*scale);
vec3 n2 = vec3(0.,1.,-g.y*scale);
vec3 n = normalize(cross(n1,n2));
outbuffer = vec4(n,value(texture(heightmap,texcoord)));
}