Working pipeline, waves WIP

This commit is contained in:
lhark 2017-11-28 12:35:49 -05:00
parent f7f6beb3dc
commit f0aa3d3fb9
12 changed files with 371 additions and 120 deletions

View file

@ -90,8 +90,10 @@ void FBO::Init( int w, int h )
// on veut des filtres de mignification et magnification de tpe NEAREST!
glGenTextures(1, &m_Texture);
glBindTexture(m_Target, m_Texture);
glTexParameteri(m_Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(m_Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(m_Target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(m_Target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri( m_Target, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( m_Target, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D(m_Target, 0, GL_RGBA32F, w, h, 0, GL_RGBA, GL_FLOAT, NULL);
// Créer une texture de profondeurs pour les couleurs avec L'ID m_Profondeur:
@ -99,6 +101,8 @@ void FBO::Init( int w, int h )
glBindTexture(m_Target, m_Profondeur);
glTexParameteri(m_Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(m_Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri( m_Target, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( m_Target, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D(m_Target, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

View file

@ -127,6 +127,12 @@ Packets::Packets(int packetBudget)
auto width = *reinterpret_cast<uint32_t *>(&info[18]);
auto height = *reinterpret_cast<uint32_t *>(&info[22]);
auto depth = *reinterpret_cast<uint16_t *>(&info[28]);
printf("Loading %s:\n", groundTexFile);
printf(" fileSize = %d\n", fileSize);
printf(" dataOffset = %d\n", dataOffset);
printf(" width = %d\n", width);
printf(" height = %d\n", height);
printf(" depth = %d\n", depth);
if (info[0] != 'B' || info[1] != 'M') {
fclose(f);
@ -175,16 +181,16 @@ Packets::Packets(int packetBudget)
{
// if we are at the boundary, intialize the distance function with 0, otherwise with maximum value
if ((bound[y*m_groundSizeX + x] > 0.5f) &&
((bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 1))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 0))] <= 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 0))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 1))] <= 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y - 1))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 0))] <= 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 0))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x - 1))] <= 0.5f)))
((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] <= 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] <= 0.5f)))
pMap[y*m_groundSizeX + x] = 0; // initialize with maximum x distance
else if ((bound[y*m_groundSizeX + x] <= 0.5f) &&
((bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 1))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 0))] > 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 0))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 1))] > 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y - 1))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x + 0))] > 0.5f)
|| (bound[max<int>(0, min<float>(m_groundSizeY - 1, y + 0))*m_groundSizeX + max<int>(0, min<float>(m_groundSizeX - 1, x - 1))] > 0.5f)))
((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] > 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f)
|| (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] > 0.5f)))
pMap[y*m_groundSizeX + x] = 0; // initialize with maximum x distance
else
pMap[y*m_groundSizeX + x] = m_groundSizeX*m_groundSizeX; // initialize with maximum x distance
@ -202,7 +208,7 @@ Packets::Packets(int packetBudget)
{
if (pMap[y*m_groundSizeX+x] == 0)
lastBoundX = x;
pMap[y*m_groundSizeX+x] = min<float>(pMap[y*m_groundSizeX+x], (x-lastBoundX)*(x-lastBoundX));
pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (x-lastBoundX)*(x-lastBoundX));
}
}
#pragma omp parallel for
@ -213,7 +219,7 @@ Packets::Packets(int packetBudget)
{
if (pMap[y*m_groundSizeX+x] == 0)
lastBoundX = x;
pMap[y*m_groundSizeX+x] = min<float>(pMap[y*m_groundSizeX+x], (lastBoundX-x)*(lastBoundX-x));
pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (lastBoundX-x)*(lastBoundX-x));
}
}
#pragma omp parallel for
@ -223,13 +229,13 @@ Packets::Packets(int packetBudget)
int minDist = pMap[y*m_groundSizeX+x];
for (int yd=1; yd+y<=m_groundSizeY-1; yd++)
{
minDist = min<float>(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]);
minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]);
if (minDist < yd*yd)
break;
}
for (int yd=-1; yd+y>=0; yd--)
{
minDist = min<float>(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]);
minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]);
if (minDist < yd*yd)
break;
}
@ -255,11 +261,11 @@ Packets::Packets(int packetBudget)
for (int y=0; y<m_groundSizeY; y++)
for (int x=0; x<m_groundSizeX; x++)
{
float dx = m_distMap[y*m_groundSizeX + max<int>(0,min<float>(m_groundSizeX-1,x+1))] - m_distMap[y*m_groundSizeX + x];
float dy = m_distMap[max<int>(0,min<float>(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + x];
float dx = m_distMap[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x+1))] - m_distMap[y*m_groundSizeX + x];
float dy = m_distMap[max(0,min(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + x];
Vector2f dV = Vector2f(dx,dy);
dx = m_distMap[y*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + max<int>(0,min<float>(m_groundSizeX-1,x-1))];
dy = m_distMap[y*m_groundSizeX + x] - m_distMap[max<int>(0,min<float>(m_groundSizeY-1,y-1))*m_groundSizeX + x];
dx = m_distMap[y*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))];
dy = m_distMap[y*m_groundSizeX + x] - m_distMap[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x];
dV += Vector2f(dx,dy);
m_bndDeriv[y*m_groundSizeX+x] = Vector2f(0,0);
if ((dV.x() != 0) || (dV.y() != 0))
@ -285,7 +291,7 @@ Packets::Packets(int packetBudget)
w = 4.0/16.0;
else if ((abs(dy) == 0) || (abs(dx) == 0))
w = 2.0/16.0;
dV += w*m_bndDeriv[max<int>(0,min<float>(m_groundSizeY-1,y+dy))*m_groundSizeX + max<int>(0,min<float>(m_groundSizeX-1,x+dx))];
dV += w*m_bndDeriv[max(0,min(m_groundSizeY-1,y+dy))*m_groundSizeX + max(0,min(m_groundSizeX-1,x+dx))];
}
if ((dV.x() != 0) || (dV.y() != 0))
m_bndDerivH[y*m_groundSizeX+x] = dV.normalized();
@ -303,11 +309,11 @@ Packets::Packets(int packetBudget)
for (int y=0; y<m_groundSizeY; y++)
for (int x=0; x<m_groundSizeX; x++)
{
float dx = m_ground[y*m_groundSizeX + max<int>(0,min<float>(m_groundSizeX-1,x+1))] - m_ground[y*m_groundSizeX + x];
float dy = m_ground[max<int>(0,min<float>(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_ground[y*m_groundSizeX + x];
float dx = m_ground[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x+1))] - m_ground[y*m_groundSizeX + x];
float dy = m_ground[max(0,min(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_ground[y*m_groundSizeX + x];
Vector2f dV = Vector2f(dx,dy);
dx = m_ground[y*m_groundSizeX + x] - m_ground[y*m_groundSizeX + max<int>(0,min<float>(m_groundSizeX-1,x-1))];
dy = m_ground[y*m_groundSizeX + x] - m_ground[max<int>(0,min<float>(m_groundSizeY-1,y-1))*m_groundSizeX + x];
dx = m_ground[y*m_groundSizeX + x] - m_ground[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))];
dy = m_ground[y*m_groundSizeX + x] - m_ground[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x];
dV += Vector2f(dx,dy);
m_gndDeriv[y*m_groundSizeX+x] = Vector2f(0,0);
if ((dV.x() != 0) || (dV.y() != 0))
@ -477,8 +483,8 @@ void Packets::DeleteGhost(int id)
void Packets::CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, float dir1x, float dir1y, float dir2x, float dir2y, float k_L, float k_H, float E)
{
// make sure we have enough memory
if ( max<float>(m_usedPackets, m_usedGhosts) + 10 > m_packetNum)
ExpandWavePacketMemory(max<float>(m_usedPackets,m_usedGhosts) + PACKET_BUFFER_DELTA);
if ( max(m_usedPackets, m_usedGhosts) + 10 > m_packetNum)
ExpandWavePacketMemory(max(m_usedPackets,m_usedGhosts) + PACKET_BUFFER_DELTA);
float speedDummy, kDummy;
int firstfree = GetFreePackedID();
m_packet[firstfree].pos1 = Vector2f(pos1x,pos1y);
@ -957,8 +963,8 @@ void Packets::AdvectWavePackets(float dTime)
// wavenumber interval subdivision if travel distance between fastest and slowest wave packets differ more than PACKET_SPLIT_DISPERSION x envelope size
if ( max<float>(m_usedGhosts + m_usedPackets, 2*m_usedPackets) > m_packetNum)
ExpandWavePacketMemory(max<float>(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA);
if ( max(m_usedGhosts + m_usedPackets, 2*m_usedPackets) > m_packetNum)
ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA);
#pragma omp parallel for
for (int uP = m_usedPackets-1; uP>=0; uP--)
if (!m_packet[m_usedPacket[uP]].use3rd)
@ -1036,8 +1042,8 @@ void Packets::AdvectWavePackets(float dTime)
// crest-refinement of packets of regular packet (not at any boundary, i.e. having no 3rd vertex)
if (max<float>(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) > m_packetNum)
ExpandWavePacketMemory(max<float>(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA);
if (max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) > m_packetNum)
ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA);
#pragma omp parallel for
for (int uP = m_usedPackets-1; uP>=0; uP--)
if (!m_packet[m_usedPacket[uP]].use3rd)

View file

@ -20,7 +20,7 @@ void main(void)
float centerDiff = length(In.Pos.zw - vec2(0, In.Att2.x)) - abs(In.Pos.w - In.Att2.x);
float phase = -In.Att1.z + (In.Pos.w + centerDiff) * 2 * PI / In.Att1.y;
/* ROLL CREDITS ! */
vec3 ripple = (1 + cos(In.Pos.x * PI)) * (1 + cos(In.Pos.y * PI)) * In.Att1.x *
vec3 ripple = (1.0 + cos(In.Pos.x * PI)) * (1.0 + cos(In.Pos.y * PI)) * In.Att1.x *
vec3(0, cos(phase), 0);
Color = vec4(ripple, 1);
}

View file

@ -43,7 +43,7 @@ void main(void)
Out.Pos = vec4(-1, -1, -In[0].Att1.w, -In[0].Att1.w);
gl_Position = matrProj * matrVisu * matrModel * p2;
EmitVertex();
Out.Pos = vec4(1, 1, -In[0].Att1.w, 0);
Out.Pos = vec4(1, 1, In[0].Att1.w, 0);
gl_Position = matrProj * matrVisu * matrModel * p3;
EmitVertex();
Out.Pos = vec4(1, -1, In[0].Att1.w, -In[0].Att1.w);

56
displayMicroMesh.frag Normal file
View file

@ -0,0 +1,56 @@
#version 410
#define PI 3.14159265359
#define SCENE_EXTENT 100.0f
uniform mat4 matrModel;
uniform mat4 matrVisu;
uniform mat4 matrProj;
uniform sampler2D terrain;
uniform sampler2D waterPos;
uniform sampler2D waterHeight;
out vec4 Color;
in Attribs {
vec3 pos;
vec2 texuv;
} In;
void main(void)
{
// the derivative of the water displacement texture gives us the water surface normal
/*TODO Linear sampler */
vec3 pos = texture(waterPos, In.texuv).rgb + texture(waterHeight, In.texuv).rgb;
vec3 N = cross(dFdx(pos), -dFdy(pos));
if (dot(N, N) <= 0.0)
N = vec3(0, -1, 0);
else
N = normalize(N);
vec3 V = normalize(In.pos - (matrVisu * matrModel)[3].xyz); /* TODO check view vector */
vec3 R = V - (2 * dot(V, N))*N; /* Reflection */
/* Diffuse + reflective lighting */
vec3 color = vec3(0.5, 0.6, 0.8);
float fac = 1.0 - (1.0 - abs(N.y) + abs(R.y)) * (1.0 - abs(N.y) + abs(R.y));
Color.rgb = fac * fac * color;
/* Add specular glares */
vec3 glareDir1 = normalize(vec3(-1, -0.75, 1));
vec3 glareDir2 = normalize(vec3( 1, -0.75, -1));
vec3 glareDir3 = normalize(vec3( 1, -0.75, 1));
vec3 glareDir4 = normalize(vec3(-1, -0.75, -1));
vec3 glareDir5 = normalize(vec3( 0, -1, 0));
Color.rgb += 100*pow(max(dot(-R, glareDir5), max(dot(-R, glareDir4), max(dot(-R, glareDir3), max(dot(-R, glareDir2), max(dot(-R, glareDir1), 0.0))))), 5000);
/* Grid overlay */
float floorFactor = 1.0;
float sth = 0.06;
float posfac = 1.2 * 80.0 / SCENE_EXTENT;
if (fract(posfac * pos.x) < sth)
floorFactor = 0.5 - 0.5 * cos(-PI + 2.0 * PI * fract(posfac * pos.x) / sth);
if (fract(posfac * pos.z) < sth)
floorFactor = min(floorFactor, 0.5 - 0.5 * cos(-PI + 2.0 * PI * fract(posfac * pos.z) / sth));
Color.rgb *= (0.75 + 0.25 * floorFactor);
/* TODO Linear sampling */
float waterDepth = 1.0 + 0.9 * pow(texture(terrain, In.pos.xz / SCENE_EXTENT + vec2(0.5)).z, 4);
Color.rgb *= waterDepth;
Color.a = 1.0;
}

33
displayMicroMesh.geom Normal file
View file

@ -0,0 +1,33 @@
#version 410
#define SCENE_EXTENT 100.0f
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
uniform mat4 matrModel;
uniform mat4 matrVisu;
uniform mat4 matrProj;
/////////////////////////////////////////////////////////////////
in Attribs {
vec3 pos;
vec2 texuv;
} In[];
out Attribs {
vec3 pos;
vec2 texuv;
} Out;
void main(void)
{
if (gl_in[0].gl_Position.w<0.01 || gl_in[1].gl_Position.w<0.01 || gl_in[2].gl_Position.w<0.01)
return;
for (int i = 0; i < 3; i++) {
Out.pos = In[i].pos;
Out.texuv = In[i].texuv;
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
}

36
displayMicroMesh.vert Normal file
View file

@ -0,0 +1,36 @@
#version 410
#define SCENE_EXTENT 100.0f
uniform mat4 matrModel;
uniform mat4 matrVisu;
uniform mat4 matrProj;
uniform sampler2D terrain;
uniform sampler2D waterPos;
uniform sampler2D waterHeight;
/////////////////////////////////////////////////////////////////
layout(location=0) in vec2 Vertex;
out Attribs {
vec3 pos;
vec2 texuv;
} Out;
// takes a simple 2D vertex on the ground plane, offsets it along y by the land or water offset and projects it on screen
void main(void)
{
Out.texuv = Vertex;
/* TODO setup Linear sampler */
vec4 pos = texture(waterPos, Vertex);
if (pos.w <= 0.0) { /* No position data -> no water here */
Out.pos = vec3(0);
gl_Position = vec4(0,0,0,-1);
} else {
/* TODO setup Linear sampler */
Out.pos = pos.xyz + texture(waterHeight, Vertex).rgb;
gl_Position = matrProj * matrVisu * matrModel * vec4(Out.pos, 1);
}
}

17
displayTerrain.frag Normal file
View file

@ -0,0 +1,17 @@
#version 410
#define PI 3.14159265359
out vec4 Color;
in Attribs {
vec3 pos;
} In;
void main(void)
{
if (In.pos.y < - 0.1)
discard; /* Fragment underwater */
Color.rgb = (0.25 + 0.75 * In.pos.y) * vec3(0.75);
Color.a = 1.0;
}

27
displayTerrain.vert Normal file
View file

@ -0,0 +1,27 @@
#version 410
#define SCENE_EXTENT 100.0f
uniform mat4 matrModel;
uniform mat4 matrVisu;
uniform mat4 matrProj;
uniform sampler2D terrain;
/////////////////////////////////////////////////////////////////
layout(location=0) in vec2 Vertex;
out Attribs {
vec3 pos;
} Out;
// takes a simple 2D vertex on the ground plane, offsets it along y by the land or water offset and projects it on screen
void main(void)
{
vec2 uv = 0.5 * (Vertex + 1);
float h = 0.001 * (-3.5 + 80 * texture(terrain, uv).r);
vec3 pos = SCENE_EXTENT * 0.5 * vec3(Vertex.x, h, Vertex.y);
Out.pos = pos;
gl_Position = matrProj * matrVisu * matrModel * vec4(pos, 1);
}

View file

@ -1,7 +1,5 @@
#version 410
uniform sampler2D tex;
in Attribs {
vec3 pos;
} In;

View file

@ -16,7 +16,7 @@ out Attribs {
void main(void)
{
Out.pos = 0.5 * SCENE_EXTENT * vec3(Vertex.x, Vertex.y, 0);
gl_Position = matrProj * matrVisu * vec4(Out.pos, 1.);
Out.pos = 0.5 * SCENE_EXTENT * vec3(Vertex.x, 0, Vertex.y);
gl_Position = matrProj * matrVisu * matrModel * vec4(Out.pos, 1.);
}

View file

@ -42,7 +42,6 @@ GLint locmatrModelRWMP = -1;
GLint locmatrVisuRWMP = -1;
GLint locmatrProjRWMP = -1;
GLint locmatrNormaleRWMP = -1;
GLint locTexRWMP = -1;
// Locations for AddPacketDisplacement shader
GLuint locPosAPD = -1;
GLuint locAtt1APD = -1;
@ -65,14 +64,15 @@ GLuint locTexCoordDMM = -1;
GLuint locmatrModelDMM = -1;
GLuint locmatrVisuDMM = -1;
GLuint locmatrProjDMM = -1;
GLuint locTexDMM = -1;
GLuint locTerrainTexDMM = -1;
GLuint locWaterPosTexDMM = -1;
GLuint locWaterHeightTexDMM = -1;
// Locationss for DisplayTerrain shader
GLuint locVertexDT = -1;
GLuint locTexCoordDT = -1;
GLuint locmatrModelDT = -1;
GLuint locmatrVisuDT = -1;
GLuint locmatrProjDT = -1;
GLuint locTexDT = -1;
GLuint locTerrainTexDT = -1;
// Locations for RenderAA shader
GLuint locVertexRAA = -1;
GLuint locTexCoordRAA = -1;
@ -95,13 +95,16 @@ GLint locmatrProjBase = -1;
GLuint vao[NB_SHADERS];
GLuint vbo[5];
GLuint ubo[4];
GLuint vbosQuad[2];
GLuint vbosQuad[2]; /* Vertex & Tex Coord */
GLuint vboPacket;
GLuint vboHeightField;
GLuint vboDMM[2]; /* Vertex & Index */
// matrices de du pipeline graphique
MatricePipeline matrModel;
MatricePipeline matrVisu;
MatricePipeline matrProj;
MatricePipeline matrProjWide;
// les formes
FormeSphere *sphere = NULL, *sphereLumi = NULL;
@ -126,6 +129,10 @@ FBO *posFBO;
FBO *heightFBO;
FBO *aaFBO;
// Terrain mesh size
const int terrainW = 1024;
const int terrainH = 1024;
// Wave Packets
Packets *packets;
int packetBudget = 10000;
@ -135,6 +142,8 @@ int packetBudget = 10000;
* vec4: for rendering x = center of wave bending circle*/
GLfloat packetData[PACKET_GPU_BUFFER_SIZE * 3 * 4];
int nIndexDMM = 0;
////////////////////////////////////////
// déclaration des variables globales //
////////////////////////////////////////
@ -210,6 +219,8 @@ struct
/* Forward declarations */
void displayPacketOutlined(int count);
void addPacketDisplacement(int count);
void displayTerrain();
void displayMicroMesh();
void verifierAngles()
@ -259,6 +270,7 @@ void updatePackets()
// TODO Setup wide projection for InitiateWaveField (RasterizeWaveMeshPosition)
heightFBO->CommencerCapture();
int displayedPackets = 0;
int packetChunk =0;
/* Standard wave packets */
@ -279,7 +291,9 @@ void updatePackets()
packetData[packetChunk++] = packets->m_packet[pk].envelope;
/* Att2 */
packetData[packetChunk++] = packets->m_packet[pk].bending;
packetChunk += 3; /* The last 3 elements aren't needed */
packetData[packetChunk++] = 0.0;
packetData[packetChunk++] = 0.0;
packetData[packetChunk++] = 0.0;
displayedPackets++;
if (packetChunk >= PACKET_GPU_BUFFER_SIZE * 3 * 4) {
glBindBuffer(GL_ARRAY_BUFFER, vboPacket);
@ -310,7 +324,9 @@ void updatePackets()
packetData[packetChunk++] = packets->m_ghostPacket[pk].envelope;
/* Att2 */
packetData[packetChunk++] = packets->m_ghostPacket[pk].bending;
packetChunk += 3; /* The last 3 elements aren't needed */
packetData[packetChunk++] = 0.0;
packetData[packetChunk++] = 0.0;
packetData[packetChunk++] = 0.0;
displayedPackets++;
if (packetChunk >= PACKET_GPU_BUFFER_SIZE * 3 * 4) {
glBindBuffer(GL_ARRAY_BUFFER, vboPacket);
@ -328,6 +344,7 @@ void updatePackets()
//displayPacketOutlined(packetChunk / 12);
/* TODO EvaluatePackets(packetChunk) */
addPacketDisplacement(packetChunk / 12);
heightFBO->TerminerCapture();
/* TODO DisplayScene */
/* TODO Get camera center */
}
@ -448,7 +465,6 @@ void chargerNuanceurs()
locmatrModelRWMP = getloc( progRasterizeWaveMeshPosition, "matrModel" , LocUniform);
locmatrVisuRWMP = getloc( progRasterizeWaveMeshPosition, "matrVisu" , LocUniform);
locmatrProjRWMP = getloc( progRasterizeWaveMeshPosition, "matrProj" , LocUniform);
locTexRWMP = getloc( progRasterizeWaveMeshPosition, "tex" , LocUniform);
}
// Load AddPacketDisplacement shader
@ -488,7 +504,9 @@ void chargerNuanceurs()
locmatrModelDMM = getloc( progDisplayMicroMesh, "matrModel" , LocUniform);
locmatrVisuDMM = getloc( progDisplayMicroMesh, "matrVisu" , LocUniform);
locmatrProjDMM = getloc( progDisplayMicroMesh, "matrProj" , LocUniform);
locTexDMM = getloc( progDisplayMicroMesh, "tex" , LocUniform);
locTerrainTexDMM = getloc( progDisplayMicroMesh, "terrain" , LocUniform);
locWaterPosTexDMM = getloc( progDisplayMicroMesh, "waterPos" , LocUniform);
locWaterHeightTexDMM = getloc( progDisplayMicroMesh, "waterHeight" , LocUniform);
}
// Load DisplayTerrain shader
@ -496,11 +514,10 @@ void chargerNuanceurs()
const GLchar *shaders[3] = {"displayTerrain.vert", NULL, "displayTerrain.frag"};
progDisplayTerrain = createShader(shaders);
locVertexDT = getloc( progDisplayTerrain, "Vertex" , LocAttrib);
locTexCoordDT = getloc( progDisplayTerrain, "TexCoord" , LocAttrib);
locmatrModelDT = getloc( progDisplayTerrain, "matrModel" , LocUniform);
locmatrVisuDT = getloc( progDisplayTerrain, "matrVisu" , LocUniform);
locmatrProjDT = getloc( progDisplayTerrain, "matrProj" , LocUniform);
locTexDT = getloc( progDisplayTerrain, "tex" , LocUniform);
locTerrainTexDT = getloc( progDisplayTerrain, "terrain" , LocUniform);
}
// Load RenderAA shader
@ -588,6 +605,40 @@ void initPacketMesh()
}
void initHeightFieldMesh()
{
GLfloat *data = new GLfloat[terrainW * terrainH * 6 * 2];
/* TODO Benchmark usefullness of parallel for */
#pragma omp parallel for
for (int y=0; y<terrainH; ++y) {
for (int x=0; x<terrainW; ++x) {
data[(y*terrainW + x) * 12 + 0] = 2.0 * (float)(x) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 1] = 2.0 * (float)(y) / terrainH - 1.0;
data[(y*terrainW + x) * 12 + 2] = 2.0 * (float)(x) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 3] = 2.0 * (float)(y+1) / terrainH - 1.0;
data[(y*terrainW + x) * 12 + 4] = 2.0 * (float)(x+1) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 5] = 2.0 * (float)(y) / terrainH - 1.0;
data[(y*terrainW + x) * 12 + 6] = 2.0 * (float)(x) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 7] = 2.0 * (float)(y+1) / terrainH - 1.0;
data[(y*terrainW + x) * 12 + 8] = 2.0 * (float)(x+1) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 9] = 2.0 * (float)(y+1) / terrainH - 1.0;
data[(y*terrainW + x) * 12 + 10] = 2.0 * (float)(x+1) / terrainW - 1.0;
data[(y*terrainW + x) * 12 + 11] = 2.0 * (float)(y) / terrainH - 1.0;
}
}
glGenBuffers(1, &vboHeightField);
glBindVertexArray(vao[DT_SHADER]);
glBindBuffer(GL_ARRAY_BUFFER, vboHeightField);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * terrainW * terrainH * 12, data, GL_STATIC_DRAW);
glVertexAttribPointer(locVertexDT, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(locVertexDT);
glBindVertexArray(0);
delete [] data;
}
// initialisation d'openGL
void initialiser()
{
@ -605,7 +656,7 @@ void initialiser()
packets = new Packets(packetBudget);
// couleur de l'arrière-plan
glClearColor( 0.4, 0.2, 0.0, 1.0 );
glClearColor( 0.5, 0.6, 0.8, 0.0 );
// activer les etats openGL
glEnable( GL_DEPTH_TEST );
@ -623,17 +674,7 @@ void initialiser()
// Initialize VBOs
initQuad();
initPacketMesh();
// créer quelques autres formes
sphere = new FormeSphere( 1.0, 32, 32 );
sphereLumi = new FormeSphere( 0.5, 10, 10 );
theiere = new FormeTheiere( );
tore = new FormeTore( 0.4, 0.8, 32, 32 );
cylindre = new FormeCylindre( 0.3, 0.3, 3.0, 32, 32 );
cone = new FormeCylindre( 0.0, 0.5, 3.0, 32, 32 );
// Update display mesh and FBOs
// redimensionner();
initHeightFieldMesh();
}
void conclure()
@ -654,14 +695,17 @@ void conclure()
delete packets;
}
void drawQuad()
/* TODO rename according to convention */
void rasterizeWaveMeshPosition()
{
glUseProgram(progRasterizeWaveMeshPosition);
glUniformMatrix4fv( locmatrProjRWMP, 1, GL_FALSE, matrProj );
glUniformMatrix4fv( locmatrProjRWMP, 1, GL_FALSE, matrProjWide );
glUniformMatrix4fv( locmatrVisuRWMP, 1, GL_FALSE, matrVisu );
glUniformMatrix4fv( locmatrModelRWMP, 1, GL_FALSE, matrModel );
glBindVertexArray(vao[RWMP_SHADER]);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glUseProgram(0);
}
void displayPacketOutlined(int count)
@ -690,6 +734,46 @@ void addPacketDisplacement(int count)
}
void displayTerrain()
{
glUseProgram(progDisplayTerrain);
glBindVertexArray(vao[DT_SHADER]);
glUniformMatrix4fv(locmatrModelDT, 1, GL_FALSE, matrModel);
glUniformMatrix4fv(locmatrVisuDT, 1, GL_FALSE, matrVisu);
glUniformMatrix4fv(locmatrProjDT, 1, GL_FALSE, matrProj);
glActiveTexture(GL_TEXTURE0); /* Default value, can be omitted */
glBindTexture(GL_TEXTURE_2D, texTerrain);
glUniform1i(locTerrainTexDT, 0);
glDrawArrays(GL_TRIANGLES, 0, terrainW * terrainH * 12);
glBindVertexArray(0);
glUseProgram(0);
}
void displayMicroMesh()
{
glUseProgram(progDisplayMicroMesh);
glBindVertexArray(vao[DMM_SHADER]);
glUniformMatrix4fv(locmatrModelDMM, 1, GL_FALSE, matrModel);
glUniformMatrix4fv(locmatrVisuDMM, 1, GL_FALSE, matrVisu);
glUniformMatrix4fv(locmatrProjDMM, 1, GL_FALSE, matrProj);
/* Setup textures */
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texTerrain);
glUniform1i(locTerrainTexDMM, 0);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, posFBO->GetRGBTex());
glUniform1i(locWaterPosTexDMM, 1);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, heightFBO->GetRGBTex());
glUniform1i(locWaterHeightTexDMM, 2);
glDrawElements(GL_TRIANGLES, nIndexDMM, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glUseProgram(0);
}
void afficherModele()
{
// Dessiner le modèle
@ -702,40 +786,17 @@ void afficherModele()
// mise à l'échelle
matrModel.Scale( 5.0, 5.0, 5.0 );
glUniformMatrix4fv( locmatrModel, 1, GL_FALSE, matrModel );
posFBO->CommencerCapture();
rasterizeWaveMeshPosition();
posFBO->TerminerCapture();
updatePackets();
displayTerrain();
displayMicroMesh();
// displayTerrain();
} matrModel.PopMatrix();
}
void afficherLumiere()
{
// Dessiner la lumiere
// tracer une ligne vers la source lumineuse
const GLfloat fact = 5.;
GLfloat coords[] =
{
LightSource[0].position.x , LightSource[0].position.y , LightSource[0].position.z,
LightSource[0].position.x+LightSource[0].spotDirection.x/fact, LightSource[0].position.y+LightSource[0].spotDirection.y/fact, LightSource[0].position.z+LightSource[0].spotDirection.z/fact
};
glLineWidth( 3.0 );
glVertexAttrib3f( locColorBase, 1.0, 1.0, 0.5 ); // jaune
glBindVertexArray( vao[1] );
matrModel.PushMatrix(); {
glBindBuffer( GL_ARRAY_BUFFER, vbo[4] );
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(coords), coords );
glDrawArrays( GL_LINES, 0, 2 );
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
glBindVertexArray( 0 );
glLineWidth( 1.0 );
// tracer la source lumineuse
matrModel.PushMatrix(); {
matrModel.Translate( LightSource[0].position.x, LightSource[0].position.y, LightSource[0].position.z );
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
sphereLumi->afficher();
} matrModel.PopMatrix(); glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
}
// fonction d'affichage
void FenetreTP::afficherScene()
@ -746,43 +807,20 @@ void FenetreTP::afficherScene()
glUseProgram( progBase );
// définir le pipeline graphique
if ( enPerspective )
{
matrProj.Perspective( 35.0, (GLdouble)largeur_ / (GLdouble)hauteur_,
0.1, 300.0 );
}
else
{
const GLfloat d = 8.0;
if ( largeur_ <= hauteur_ )
{
matrProj.Ortho( -d, d,
-d*(GLdouble)hauteur_ / (GLdouble)largeur_,
d*(GLdouble)hauteur_ / (GLdouble)largeur_,
0.1, 300.0 );
}
else
{
matrProj.Ortho( -d*(GLdouble)largeur_ / (GLdouble)hauteur_,
d*(GLdouble)largeur_ / (GLdouble)hauteur_,
-d, d,
0.1, 300.0 );
}
}
matrProj.Perspective( 45.0, (GLdouble)largeur_ / (GLdouble)hauteur_, 0.5, 4000.0 );
matrProjWide.Perspective( 60.0, (GLdouble)largeur_ / (GLdouble)hauteur_, 0.1, 15000.0 );
glUniformMatrix4fv( locmatrProjBase, 1, GL_FALSE, matrProj );
matrVisu.LookAt( 0.0, 3.0, distCam, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
//matrVisu.LookAt( 0.0, 3.0, distCam, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
matrVisu.LookAt( 10.17, 22.13, 59.49, 10.17, 21.66, 58.61, 0.0, 1.0, 0.0 );
glUniformMatrix4fv( locmatrVisuBase, 1, GL_FALSE, matrVisu );
matrModel.LoadIdentity();
glUniformMatrix4fv( locmatrModelBase, 1, GL_FALSE, matrModel );
// afficher les axes
if ( afficheAxes ) FenetreTP::afficherAxes( 8.0 );
// dessiner la scène
//glActiveTexture( GL_TEXTURE0 ); // activer la texture '0' (valeur de défaut)
glUniform1i( loclaTexture, 0 ); // '0' => utilisation de GL_TEXTURE0
if ( afficheAxes ) FenetreTP::afficherAxes( 1.0 );
afficherModele();
}
@ -793,13 +831,49 @@ void FenetreTP::redimensionner( GLsizei w, GLsizei h )
std::cout << "Resizing to " << w << "×" << h << std::endl;
/* FIXME Is this function called on program start ? */
glViewport( 0, 0, w, h );
/* TODO Create/resize display mesh */
posFBO->Liberer();
posFBO->Init(WAVETEX_WIDTH_FACTOR * w, WAVETEX_HEIGHT_FACTOR * h);
heightFBO->Liberer();
heightFBO->Init(WAVETEX_WIDTH_FACTOR * w, WAVETEX_HEIGHT_FACTOR * h);
aaFBO->Liberer();
aaFBO->Init(AA_OVERSAMPLE_FACTOR * w, AA_OVERSAMPLE_FACTOR * h);
/* Create/resize display mesh */
int meshW = WAVEMESH_WIDTH_FACTOR * w; /*Ça fait un gros mouton */
int meshH = WAVEMESH_HEIGHT_FACTOR * h;
GLfloat *mesh = new GLfloat[meshW * meshH * 2];
nIndexDMM = 3 * 2 * (meshW - 1) * (meshH -1);
GLuint *index = new GLuint[nIndexDMM];
#pragma omp parallel for
for (int y = 0; y < meshH; ++y) {
for (int x = 0; x < meshW; ++x) {
mesh[(y * meshW + x) * 2 + 0] = (x + 0.5) / meshW;
mesh[(y * meshW + x) * 2 + 1] = (y + 0.5) / meshH;
}
}
#pragma omp parallel for
for (int y = 0; y < meshH - 1; ++y) {
for (int x = 0; x < meshW - 1; ++x) {
index[(y * (meshW - 1) + x) * 6 + 0] = y * meshW + x;
index[(y * (meshW - 1) + x) * 6 + 1] = y * meshW + x + 1;
index[(y * (meshW - 1) + x) * 6 + 2] = (y + 1) * meshW + x;
index[(y * (meshW - 1) + x) * 6 + 3] = y * meshW + x + 1;
index[(y * (meshW - 1) + x) * 6 + 4] = (y + 1) * meshW + x + 1;
index[(y * (meshW - 1) + x) * 6 + 5] = (y + 1) * meshW + x;
}
}
glGenBuffers(2, vboDMM);
glBindVertexArray(vao[DMM_SHADER]);
glBindBuffer(GL_ARRAY_BUFFER, vboDMM[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * meshW * meshH * 2, mesh, GL_STATIC_DRAW);
glVertexAttribPointer(locVertexDMM, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(locVertexDMM);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboDMM[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * nIndexDMM, index, GL_STATIC_DRAW);
glBindVertexArray(0);
delete [] mesh;
delete [] index;
}
static void echoEtats( )