Skip to content

Commit 273ecae

Browse files
committed
visual improvements for the earth
1 parent e8fb251 commit 273ecae

File tree

8 files changed

+111
-47
lines changed

8 files changed

+111
-47
lines changed

resources/shader/basic.vert

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
#version 330
22
layout (location = 0) in vec3 coord3d;
33
layout (location = 1) in vec3 v_color;
4-
layout (std140) uniform Global{ mat4 modelview; mat4 projection; mat4 normal_transform;};
4+
layout (std140) uniform Global{
5+
mat4 model;
6+
mat4 view;
7+
mat4 projection;
8+
mat4 scaling;
9+
mat4 sun_angle;
10+
};
11+
512
varying vec3 f_color;
613

714
void main(void) {
8-
vec4 camera_coords = modelview * vec4(coord3d, 1.0);
15+
vec4 camera_coords = view * model * scaling * vec4(coord3d, 1.0);
916
gl_Position = projection * camera_coords;
1017
f_color = v_color;
1118
}

resources/shader/earth.frag

+39-14
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
11
#version 330
2-
uniform sampler2D texture;
2+
uniform sampler2D earth_day;
3+
uniform sampler2D earth_water;
4+
35
varying vec2 f_texcoord;
4-
varying vec3 f_normal;
6+
varying vec4 f_normal;
57
varying vec3 f_coord3d;
6-
layout (std140) uniform Global{ mat4 modelview; mat4 projection; mat4 normal_transform;};
8+
layout (std140) uniform Global{
9+
mat4 model;
10+
mat4 view;
11+
mat4 projection;
12+
mat4 scaling;
13+
mat4 sun_angle;
14+
};
715

816
void main(void) {
917
float ambient = 0.09;
10-
vec3 light_source = (modelview * vec4(0.0, 0.0, 4.0, 1.0)).xyz;
11-
vec3 N = normalize((normal_transform * vec4(f_normal, 1.0)).xyz);
12-
vec3 L = normalize(light_source - f_coord3d); // light source
13-
vec3 V = normalize(-f_coord3d); // view
14-
vec3 R = -reflect(L, N); // reflection vector
18+
vec3 light_source = (model * sun_angle * vec4(0.0, 0.0, 20.0, 1.0)).xyz;
19+
vec3 N = normalize(f_normal).xyz;
20+
vec3 L = light_source - f_coord3d; // light source
21+
float sqr_distance = dot(L, L);
22+
L = normalize(L);
23+
vec3 V = -normalize(f_coord3d - inverse(view)[3].xyz);
24+
vec3 R = -reflect(L, N);
25+
26+
float lambertian = max(dot(N, L), 0.0);
27+
float specular = 0.0;
28+
float spec_angle = max(dot(V, R), 0.0);
29+
specular = pow(spec_angle, 20);
30+
31+
vec3 earth_color = vec3(texture2D(earth_day, f_texcoord + vec2(0.5, 0.0)));
32+
vec3 water_map = vec3(texture2D(earth_water, f_texcoord + vec2(0.5, 0.0))); // black where water
33+
float is_water = (water_map.r + water_map.g + water_map.b) / 3.0; // 0 -> land
34+
if(is_water <= 0.1){
35+
specular *= min(is_water + 0.15, 1);
36+
}
37+
vec3 diffuse_color = earth_color;
38+
vec3 light_color = vec3(0.89, 0.855, 0.686) * 500.0;
39+
40+
vec3 output_color = vec3(0.0);
41+
output_color += diffuse_color * vec3(0.07); // ambient
42+
output_color += diffuse_color * lambertian * light_color / sqr_distance; // diffuse
43+
output_color += 0.2 * vec3(1.0) * specular * light_color / sqr_distance; // specular
1544

16-
float diffuse = 0.8 * max(0.0, dot(L, N));
17-
float e = 21.0;
18-
vec3 specular = 0.4 * pow(max(0.0, dot(V, R)), e) * vec3(0.89, 0.855, 0.686) ;
19-
vec3 color = min(1.0, diffuse + ambient) * vec3(texture2D(texture, f_texcoord)) + specular;
20-
gl_FragColor = vec4(color, 1.0);
21-
}
45+
gl_FragColor = vec4(output_color, 1.0);
46+
}

resources/shader/earth.vert

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22
layout (location = 0) in vec3 coord3d;
33
layout (location = 1) in vec2 texcoord;
44
layout (location = 2) in vec3 normal;
5-
layout (std140) uniform Global{ mat4 modelview; mat4 projection; mat4 normal_transform;};
5+
layout (std140) uniform Global{
6+
mat4 model;
7+
mat4 view;
8+
mat4 projection;
9+
mat4 scaling;
10+
mat4 sun_angle;
11+
};
12+
613
varying vec2 f_texcoord;
7-
varying vec3 f_normal;
14+
varying vec4 f_normal;
815
varying vec3 f_coord3d;
916

1017
void main(void) {
11-
vec4 camera_coords = modelview * vec4(coord3d, 1.0);
12-
gl_Position = projection * camera_coords;
18+
vec4 camera_coords = model * vec4(coord3d, 1.0);
19+
gl_Position = projection * view * scaling * camera_coords;
1320

1421
f_texcoord = texcoord;
15-
f_normal = normal;
22+
f_normal = model * vec4(normal, 0);
1623
f_coord3d = camera_coords.xyz;
1724
}

resources/shader/satellite.vert

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
#version 330
22
layout (location = 0) in vec3 coord3d;
33
layout (location = 1) in vec3 offset;
4-
layout (std140) uniform Global{ mat4 modelview; mat4 projection; mat4 normal_transform;};
4+
layout (std140) uniform Global{
5+
mat4 model;
6+
mat4 view;
7+
mat4 projection;
8+
mat4 scaling;
9+
mat4 sun_angle;
10+
};
11+
512
varying vec3 f_color;
613

714
void main(void) {
815
vec3 position = coord3d + offset;
9-
vec4 camera_coords = modelview * vec4(position, 1.0);
16+
vec4 camera_coords = view * model * scaling * vec4(position, 1.0);
1017
gl_Position = projection * camera_coords;
1118
f_color = vec3(1.0, 1.0, 1.0);
1219
}

resources/textures/earth_clouds.jpg

-810 KB
Binary file not shown.

src/opengl_primitives.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ Object OpenGLPrimitives::createSphere(const float radius, const glm::vec3 center
9292
Object OpenGLPrimitives::createSatellite() {
9393
Object model = Object();
9494
model.gl_draw_mode = GL_TRIANGLES;
95-
const float cube_length = 0.005f;
9695

9796
return createSphere(0.005f, glm::vec3(0.0f), 10);
9897
}

src/opengl_widgets.cpp

+39-21
Original file line numberDiff line numberDiff line change
@@ -157,22 +157,29 @@ void OpenGLWidget::init() {
157157
glUniformBlockBinding(earth_prog, index, 1);
158158

159159
// load textures
160+
loadTextures("earth_day", uniform_texture_location[0], "textures/earth_day.jpg", texture_id[0]);
161+
loadTextures("earth_water", uniform_texture_location[1], "textures/earth_water.jpg", texture_id[1]);
162+
}
163+
164+
// ------------------------------------------------------------------------------------------------
165+
166+
void OpenGLWidget::loadTextures(const char* uniform_name, GLint& tex_location, const char* file, GLuint& id) {
160167
int w, h;
161168
int channels;
162169
unsigned char* image;
163-
const char* filename = "textures/earth_day.jpg";
164170
stbi_set_flip_vertically_on_load(1);
165-
image = stbi_load(filename, &w, &h, &channels, STBI_rgb);
171+
image = stbi_load(file, &w, &h, &channels, STBI_rgb);
166172

167173
if (image == nullptr) {
168-
printf("Failed to load image %s\n", filename);
174+
printf("Failed to load image %s\n", file);
169175
assert(false);
170176
exit(EXIT_FAILURE);
171177
}
172178

173-
glGenTextures(1, &texture_id);
174-
glBindTexture(GL_TEXTURE_2D, texture_id);
175-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
179+
glGenTextures(1, &id);
180+
glBindTexture(GL_TEXTURE_2D, id);
181+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
182+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
176183
glTexImage2D(GL_TEXTURE_2D, 0,
177184
GL_RGB, // internalformat
178185
w, h, 0,
@@ -181,9 +188,8 @@ void OpenGLWidget::init() {
181188
stbi_image_free(image);
182189

183190
// bind texture uniform
184-
const char* uniform_name = "texture"; // name of uniform in shader
185-
uniform_texture_location = glGetUniformLocation(earth_prog, uniform_name);
186-
if (uniform_texture_location == -1) {
191+
tex_location = glGetUniformLocation(earth_prog, uniform_name);
192+
if (tex_location == -1) {
187193
std::cout << "Could not bind uniform " << uniform_name << std::endl;
188194
}
189195
}
@@ -193,7 +199,7 @@ void OpenGLWidget::init() {
193199
void OpenGLWidget::show(const PhysicalInstance& instance, const float t0) {
194200
visualizeInstance(instance);
195201
sim_time = t0;
196-
glm::vec3 clear_color = glm::vec3(0.15f, 0.15f, 0.15f);
202+
glm::vec3 clear_color = glm::vec3(0.03f);
197203

198204
// Main loop
199205
while (!glfwWindowShouldClose(window)) {
@@ -221,7 +227,7 @@ void OpenGLWidget::show(const PhysicalInstance& instance, const float t0) {
221227

222228
void OpenGLWidget::show(const PhysicalInstance& instance, const Solution& solution) {
223229
visualizeSolution(instance, solution);
224-
glm::vec3 clear_color = glm::vec3(0.15f, 0.15f, 0.15f);
230+
glm::vec3 clear_color = glm::vec3(0.03f);
225231

226232
// Main loop
227233
while (!glfwWindowShouldClose(window)) {
@@ -250,10 +256,14 @@ void OpenGLWidget::show(const PhysicalInstance& instance, const Solution& soluti
250256
void OpenGLWidget::renderScene() {
251257
recalculate();
252258

253-
// bind texture
259+
// bind textures
254260
glActiveTexture(GL_TEXTURE0);
255-
glUniform1i(uniform_texture_location, /*GL_TEXTURE*/ 0);
256-
glBindTexture(GL_TEXTURE_2D, texture_id);
261+
glUniform1i(uniform_texture_location[0], /*GL_TEXTURE*/ 0);
262+
glBindTexture(GL_TEXTURE_2D, texture_id[0]);
263+
264+
glActiveTexture(GL_TEXTURE1);
265+
glUniform1i(uniform_texture_location[1], /*GL_TEXTURE*/ 1);
266+
glBindTexture(GL_TEXTURE_2D, texture_id[1]);
257267

258268
// Draw the scene:
259269
for (const Subscene& s : scene) {
@@ -273,6 +283,10 @@ void OpenGLWidget::recalculate() {
273283
if (!paused)
274284
sim_time += diff * sim_speed;
275285

286+
// sun rotation
287+
float sun_angle = sim_time * 0.000290f; // 6h -> one turn around the earth
288+
glm::mat4 sun_rotation = glm::rotate(glm::mat4(1.f), sun_angle, glm::vec3(0.f, 1.f, 0.f));
289+
276290
/* Camera circumnavigating around the central mass.
277291
* Instead of performing two rotations for the camera, the rotation around the y-axis is done by rotation the entire
278292
* world itself. */
@@ -294,15 +308,17 @@ void OpenGLWidget::recalculate() {
294308
glGetIntegerv(GL_VIEWPORT, viewport);
295309
projection = glm::perspective(45.0f, 1.0f * viewport[2] / viewport[3], 0.1f, 10.0f);
296310
glm::mat4 scale = glm::scale(glm::vec3(1.0f) * zoom);
297-
glm::mat4 modelview = view * world_rotation * scale;
298-
glm::mat4 normal_proj = glm::transpose(glm::inverse(modelview));
311+
glm::mat4 model = world_rotation;
312+
// glm::mat4 normal_proj = glm::transpose(glm::inverse(modelview));
299313

300314
// push mvp to VBO
301315
glBindBuffer(GL_UNIFORM_BUFFER, vbo_uniforms);
302-
glBufferData(GL_UNIFORM_BUFFER, 3 * sizeof(glm::mat4), 0, GL_STREAM_DRAW);
303-
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(modelview));
304-
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(projection));
305-
glBufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(normal_proj));
316+
glBufferData(GL_UNIFORM_BUFFER, 5 * sizeof(glm::mat4), 0, GL_STREAM_DRAW);
317+
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(model));
318+
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
319+
glBufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(projection));
320+
glBufferSubData(GL_UNIFORM_BUFFER, 3 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(scale));
321+
glBufferSubData(GL_UNIFORM_BUFFER, 4 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(sun_rotation));
306322
glBindBuffer(GL_UNIFORM_BUFFER, 0);
307323

308324
// dynamic part of scene
@@ -762,7 +778,9 @@ void OpenGLWidget::destroy() {
762778
deleteInstance();
763779
glDeleteProgram(basic_program);
764780
glDeleteProgram(satellite_prog);
765-
glDeleteTextures(1, &texture_id);
781+
glDeleteTextures(1, &texture_id[0]);
782+
glDeleteTextures(1, &texture_id[1]);
783+
glDeleteTextures(1, &texture_id[2]);
766784

767785
glfwDestroyWindow(window);
768786
glfwTerminate();

src/opengl_widgets.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class OpenGLWidget {
3838
void recalculateEdges();
3939
void deleteInstance();
4040
void pushSceneToGPU();
41+
void loadTextures(const char* uniform_name, GLint& tex_location, const char* file, GLuint& id);
4142

4243
/**
4344
* @brief Convert a given instance with orbits and communications between the satellites into an opengl
@@ -83,8 +84,8 @@ class OpenGLWidget {
8384
// Handler
8485
GLuint basic_program = 0, satellite_prog = 0, earth_prog = 0;
8586
GLuint vbo_uniforms = 0;
86-
GLuint texture_id = 0;
87-
GLint uniform_texture_location = 0;
87+
GLuint texture_id[2] = {0, 0};
88+
GLint uniform_texture_location[2] = {-1, -1};
8889
// view and camera
8990
float zoom = 1.0f;
9091
glm::vec2 camera_rotation_angle_offset = glm::vec2(.0f, .0f);

0 commit comments

Comments
 (0)