Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
create a interpolated heightmap (640x640) from vertices[.].y (64x64).
But it is a little expensive.
  • Loading branch information
iamyoukou committed Jun 20, 2020
1 parent 200a43e commit 46d4732
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 77 deletions.
2 changes: 1 addition & 1 deletion header/ocean.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class cOcean {
Complex hTilde(float t, int n_prime, int m_prime);
void evaluateWavesFFT(float t);
void render(float t, glm::vec3 light_pos, glm::mat4 Projection,
glm::mat4 View, glm::mat4 Model, bool resume);
glm::mat4 View, glm::mat4 Model, bool resume, int frameN);
void computeWaterGeometry();
void updateWaterGeometry();
void drawPoints();
Expand Down
160 changes: 85 additions & 75 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) {
// ocean
glDisable(GL_CULL_FACE);
ocean.render(timer.elapsed(false), vec3(20, 20, 20), oceanP, oceanV, oceanM,
simulation);
simulation, frameNumber);

/* render to main screen */
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Expand All @@ -104,84 +104,90 @@ int main(int argc, char *argv[]) {
glUseProgram(shaderScreenQuad);

/* calculate the threshold for the condition of underwater */
// project the eyePoint onto the ocean surface
// calculate which ocean cell it is in
vec3 temp = eyePoint;
// vec3 tempDir = normalize(vec3(eyeDirection.x, 0, eyeDirection.z));
// temp += eyeDirection * 2.f;

int ix = floor(temp.x / ocean.cellSize);
int iz = floor(temp.z / ocean.cellSize);

vec3 ref(ix * ocean.cellSize, 0, iz * ocean.cellSize);

// std::cout << "cell index (before): " << to_string(vec2(ix, iz)) << '\n';

// if eyePoint is over the duplicated area,
// transform the indices back to the original area
while (ix > ocean.N / 2)
ix -= ocean.N;
while (ix < -ocean.N / 2)
ix += ocean.N;
while (iz > ocean.N / 2)
iz -= ocean.N;
while (iz < -ocean.N / 2)
iz += ocean.N;

// std::cout << "cell index (after): " << to_string(vec2(ix, iz)) << '\n';

// ix, iz is [- N/2, N/2]
// change to [0, N] to access ocean vertices
ix += ocean.N / 2;
iz += ocean.N / 2;
// // project the eyePoint onto the ocean surface
// // calculate which ocean cell it is in
// vec3 temp = eyePoint;
// // vec3 tempDir = normalize(vec3(eyeDirection.x, 0, eyeDirection.z));
// // temp += eyeDirection * 2.f;
//
vec3 A, B, C, D;
A = ocean.getVertex(ix, iz);
B = ocean.getVertex(ix + 1, iz);
C = ocean.getVertex(ix + 1, iz + 1);
D = ocean.getVertex(ix, iz + 1);
// int ix = floor(temp.x / ocean.cellSize);
// int iz = floor(temp.z / ocean.cellSize);
//
// vec3 whichVtx = ocean.getVertex(ix, iz);
// vec3 ref(ix * ocean.cellSize, 0, iz * ocean.cellSize);
//
float alpha = (temp.z - ref.z) / ocean.cellSize;
float beta = (temp.x - ref.x) / ocean.cellSize;
// // std::cout << "cell index (before): " << to_string(vec2(ix, iz)) <<
// '\n';
//
float Z1 = (1.f - alpha) * A.y + alpha * D.y;
float Z2 = (1.f - alpha) * B.y + alpha * C.y;
float Z = (1.f - beta) * Z1 + beta * Z2;

float threshold = Z;
float everage = (A.y + B.y + C.y + D.y) * 0.25;

// if (simulation) {
// std::cout << "alpha = " << alpha << '\n';
// std::cout << "beta = " << beta << '\n';
// // if eyePoint is over the duplicated area,
// // transform the indices back to the original area
// while (ix > ocean.N / 2)
// ix -= ocean.N;
// while (ix < -ocean.N / 2)
// ix += ocean.N;
// while (iz > ocean.N / 2)
// iz -= ocean.N;
// while (iz < -ocean.N / 2)
// iz += ocean.N;
//
// // std::cout << "cell index (after): " << to_string(vec2(ix, iz)) <<
// '\n';
//
// // ix, iz is [- N/2, N/2]
// // change to [0, N] to access ocean vertices
// ix += ocean.N / 2;
// iz += ocean.N / 2;
// //
// vec3 A, B, C, D;
// A = ocean.getVertex(ix, iz);
// B = ocean.getVertex(ix + 1, iz);
// C = ocean.getVertex(ix + 1, iz + 1);
// D = ocean.getVertex(ix, iz + 1);
// //
// // vec3 whichVtx = ocean.getVertex(ix, iz);
// //
// float alpha = (temp.z - ref.z) / ocean.cellSize;
// float beta = (temp.x - ref.x) / ocean.cellSize;
// //
// float Z1 = (1.f - alpha) * A.y + alpha * D.y;
// float Z2 = (1.f - alpha) * B.y + alpha * C.y;
// float Z = (1.f - beta) * Z1 + beta * Z2;
//
// float threshold = Z;
// float everage = (A.y + B.y + C.y + D.y) * 0.25;
//
// // if (simulation) {
// // std::cout << "alpha = " << alpha << '\n';
// // std::cout << "beta = " << beta << '\n';
// //
// // // std::cout << "whichVtx: " << to_string(whichVtx) << '\n';
// // std::cout << "temp: " << to_string(eyePoint) << '\n';
// // std::cout << "belongs to: " << to_string(ocean.getVertex(ix, iz)) <<
// // '\n'; std::cout << "A: " << to_string(A) << '\n'; std::cout << "B: "
// <<
// // to_string(B) << '\n'; std::cout << "C: " << to_string(C) << '\n';
// // std::cout << "D: " << to_string(D) << '\n';
// // std::cout << "ref: " << to_string(ref) << '\n';
// // // std::cout << '\n';
// // // std::cout << "cell index (access): " << to_string(vec2(ix, iz))
// <<
// // // '\n';
// // // std::cout << to_string(ocean.getVertex(ix + 1, iz)) << '\n';
// // // std::cout << to_string(ocean.getVertex(ix, iz + 1)) << '\n';
// // // std::cout << to_string(ocean.getVertex(ix + 1, iz + 1)) <<
// '\n';
// // std::cout << "threshold: " << threshold << '\n';
// // std::cout << "everage: " << everage << '\n';
// // // std::cout << to_string(ocean.getVertex(5, 17)) << '\n';
// // std::cout << '\n';
// // }
//
// // std::cout << "whichVtx: " << to_string(whichVtx) << '\n';
// std::cout << "temp: " << to_string(eyePoint) << '\n';
// std::cout << "belongs to: " << to_string(ocean.getVertex(ix, iz)) <<
// '\n'; std::cout << "A: " << to_string(A) << '\n'; std::cout << "B: " <<
// to_string(B) << '\n'; std::cout << "C: " << to_string(C) << '\n';
// std::cout << "D: " << to_string(D) << '\n';
// std::cout << "ref: " << to_string(ref) << '\n';
// // std::cout << '\n';
// // std::cout << "cell index (access): " << to_string(vec2(ix, iz)) <<
// // '\n';
// // std::cout << to_string(ocean.getVertex(ix + 1, iz)) << '\n';
// // std::cout << to_string(ocean.getVertex(ix, iz + 1)) << '\n';
// // std::cout << to_string(ocean.getVertex(ix + 1, iz + 1)) << '\n';
// std::cout << "threshold: " << threshold << '\n';
// std::cout << "everage: " << everage << '\n';
// // std::cout << to_string(ocean.getVertex(5, 17)) << '\n';
// std::cout << '\n';
// // for underwater scene
// if (eyePoint.y < threshold) {
// glUniform1f(uniAlpha, 0.5f);
// }
// else {
// glUniform1f(uniAlpha, 1.f);
// }

// for underwater scene
if (eyePoint.y < threshold) {
glUniform1f(uniAlpha, 0.5f);
} else {
glUniform1f(uniAlpha, 1.f);
}

glBindVertexArray(vaoScreenQuad);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Expand All @@ -208,13 +214,15 @@ int main(int argc, char *argv[]) {
(GLvoid *)FreeImage_GetBits(outputImage));
FreeImage_Save(FIF_BMP, outputImage, output.c_str(), 0);
std::cout << output << " saved." << '\n';
frameNumber++;
}

frameNumber++;
}

// release
ocean.release();

glfwTerminate();
FreeImage_DeInitialise();

return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -449,6 +457,8 @@ void initOther() {
// initialize random seed
// this makes the ocean geometry different in every execution
srand(clock());

FreeImage_Initialise(true);
}

void initScreenQuad() {
Expand Down
63 changes: 62 additions & 1 deletion src/ocean.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,75 @@ void cOcean::evaluateWavesFFT(float t) {
}

void cOcean::render(float t, glm::vec3 light_pos, glm::mat4 Projection,
glm::mat4 View, glm::mat4 Model, bool resume) {
glm::mat4 View, glm::mat4 Model, bool resume, int frameN) {
if (resume) {
evaluateWavesFFT(t);
}

computeWaterGeometry();
updateWaterGeometry();

// create height map
// a little expensive
FIBITMAP *heightMap = FreeImage_Allocate(N * 10, N * 10, 24);
RGBQUAD color;

if (!heightMap) {
std::cout << "FreeImage: Cannot allocate image." << '\n';
exit(EXIT_FAILURE);
}

int nOfInter = 10; // # of interpolation points between two vertices.

// note: the difference of query order between image and vertices[.]
// image: top-down, left-right
// vertices: bottom-up, left-right
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
int idx0 = r * Nplus1 + c; // query vertices[.]
int idx1 = idx0 + 1;
int idx2 = idx1 + Nplus1;
int idx3 = idx2 - 1;

// a local quad
for (size_t k = 0; k < nOfInter; k++) {
for (size_t l = 0; l < nOfInter; l++) {
float alpha = k * 0.1f;
float beta = l * 0.1f;

float Ay = vertices[idx0].y;
float By = vertices[idx1].y;
float Cy = vertices[idx2].y;
float Dy = vertices[idx3].y;

float E1y = (1 - alpha) * Ay + alpha * Dy;
float E2y = (1 - alpha) * By + alpha * Cy;
float Ey = (1 - beta) * E1y + beta * E2y;

color.rgbRed = abs(Ey) * 100.0;
// std::cout << abs(Ey) << '\n';

color.rgbGreen = (Ey < 0) ? 0 : 1;
color.rgbBlue = 0;

FreeImage_SetPixelColor(heightMap, c * nOfInter + l,
(N - 1 - r) * nOfInter + (nOfInter - 1 - k),
&color);
}
}
}
}

string dir = "./result/heightMap";
// zero padding
// e.g. "heightMap0001.bmp"
string num = to_string(frameN);
num = string(4 - num.length(), '0') + num;
string output = dir + num + ".png";

if (FreeImage_Save(FIF_PNG, heightMap, output.c_str(), 0))
cout << output << " saved!" << endl;

// update transform matrix
glUseProgram(shader);
glUniform3f(light_position, light_pos.x, light_pos.y, light_pos.z);
Expand Down
Binary file added test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 46d4732

Please sign in to comment.