mirror of
https://github.com/SatDump/SatDump
synced 2026-08-13 17:47:30 -04:00
934 lines
No EOL
36 KiB
C++
934 lines
No EOL
36 KiB
C++
#pragma once
|
|
|
|
#include "common/geodetic/geodetic_coordinates.h"
|
|
#include "common/geodetic/lla_xyz.h"
|
|
#include "common/tracking/tle.h"
|
|
#include "core/resources.h"
|
|
#include "image/image.h"
|
|
#include "image/io.h"
|
|
#include "imgui/imgui.h"
|
|
#include "imgui/imgui_image.h"
|
|
#include "init.h"
|
|
#include "libs/predict/predict.h"
|
|
#include "logger.h"
|
|
|
|
#include "../src-ui/gl.h"
|
|
#include "utils/time.h"
|
|
#include <GL/gl.h>
|
|
|
|
#include <GLES3/gl3.h>
|
|
#include <glm/glm.hpp>
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
#include <iostream>
|
|
|
|
/*
|
|
THIS CODE IS ABSOLUTE GARBAGE MADE LITERALLY AS FAST POSSIBLE, DO NOT JUDGE.... LITERALLY ONLY FOR A DEMO ASKED BY LEGO11.
|
|
Aang23
|
|
|
|
(the base OpenGL code is like, over 6-7 years old or such, copy-pasted to do it ASAP)
|
|
*/
|
|
|
|
static GLfloat g_vertex_buffer_data[] = {
|
|
1.0f, 0.0f, 0.0f, //
|
|
-1.0f, 0.0f, 0.0f, //
|
|
0.0f, 1.0f, 0.0f, //
|
|
|
|
-1.0f, 0.0f, 0.0f, //
|
|
1.0f, 0.0f, 0.0f, //
|
|
0.0f, -1.0f, 0.0f, //
|
|
};
|
|
|
|
// Two UV coordinatesfor each vertex. They were created with Blender.
|
|
static GLfloat g_uv_buffer_data[] = {
|
|
1, 1, //
|
|
0, 0, //
|
|
0, 1, //
|
|
|
|
-1, -1, //
|
|
0, 0, //
|
|
0, -1, //
|
|
};
|
|
|
|
class VertObject
|
|
{
|
|
public:
|
|
std::vector<float> vertices_buf;
|
|
std::vector<float> textpos_buf;
|
|
GLuint vertexbuffer;
|
|
GLuint uvbuffer;
|
|
|
|
public:
|
|
void addPoint(float x, float y, float z, float tex_x, float tex_y)
|
|
{
|
|
vertices_buf.push_back(x);
|
|
vertices_buf.push_back(y);
|
|
vertices_buf.push_back(z);
|
|
|
|
textpos_buf.push_back(tex_x);
|
|
textpos_buf.push_back(tex_y);
|
|
}
|
|
|
|
void addRect(float c1_x, float c1_y, float c1_z, //
|
|
float c2_x, float c2_y, float c2_z, //
|
|
float c3_x, float c3_y, float c3_z, //
|
|
float c4_x, float c4_y, float c4_z, //
|
|
float t1_x, float t1_y, //
|
|
float t2_x, float t2_y, //
|
|
float t3_x, float t3_y, //
|
|
float t4_x, float t4_y)
|
|
{
|
|
addPoint(c1_x, c1_y, c1_z, t1_x, t1_y);
|
|
addPoint(c2_x, c2_y, c2_z, t2_x, t2_y);
|
|
addPoint(c4_x, c4_y, c4_z, t4_x, t4_y);
|
|
|
|
addPoint(c2_x, c2_y, c2_z, t2_x, t2_y);
|
|
addPoint(c3_x, c3_y, c3_z, t3_x, t3_y);
|
|
addPoint(c4_x, c4_y, c4_z, t4_x, t4_y);
|
|
}
|
|
};
|
|
|
|
class OpenGLScene
|
|
{
|
|
public:
|
|
predict_orbital_elements_t *satellite_object = nullptr;
|
|
predict_position satellite_orbit;
|
|
|
|
predict_orbital_elements_t *satellite_object2 = nullptr;
|
|
predict_position satellite_orbit2;
|
|
|
|
private:
|
|
GLuint program;
|
|
|
|
GLuint VertexArrayID;
|
|
|
|
// STUFF
|
|
GLuint FramebufferName = 0;
|
|
GLuint renderedTexture;
|
|
GLuint depthrenderbuffer;
|
|
|
|
GLuint MatrixID;
|
|
|
|
glm::mat4 Projection;
|
|
glm::mat4 View;
|
|
glm::mat4 Model;
|
|
glm::mat4 MVP;
|
|
|
|
GLuint TextureID;
|
|
GLuint Texture;
|
|
GLuint Texture2;
|
|
GLuint Texture3;
|
|
|
|
const int render_width = 1024 * 4;
|
|
const int render_height = 768 * 4;
|
|
|
|
VertObject earthSphere;
|
|
VertObject meteorSphere;
|
|
VertObject noaaSphere;
|
|
|
|
public:
|
|
OpenGLScene()
|
|
{
|
|
auto tle = satdump::db_tle->get_from_norad(40069);
|
|
satellite_object = predict_parse_tle(tle->line1.c_str(), tle->line2.c_str());
|
|
|
|
auto tle2 = satdump::db_tle->get_from_norad(25338);
|
|
satellite_object2 = predict_parse_tle(tle2->line1.c_str(), tle2->line2.c_str());
|
|
|
|
// Original
|
|
{
|
|
float latc = 500;
|
|
float lonc = latc * 2; // 100;
|
|
float radius = 5;
|
|
|
|
float lat_delta_angle = (M_PI) / latc;
|
|
float lon_delta_angle = (M_PI * 2) / lonc;
|
|
|
|
float lat_text_delta = 1.0f / latc;
|
|
float lon_text_delta = 1.0f / lonc;
|
|
|
|
for (float latn = 0; latn < latc; latn++) // The poles are made from triangles... Skip them
|
|
{
|
|
for (float lonn = 0; lonn < lonc; lonn++)
|
|
{
|
|
float lat = (latn - (latc / 2)) * lat_delta_angle;
|
|
float lon = lonn * lon_delta_angle;
|
|
|
|
float x1 = radius * cos(lat) * cos(lon);
|
|
float y1 = radius * cos(lat) * sin(lon);
|
|
float z1 = radius * sin(lat);
|
|
|
|
lat += lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x2 = radius * cos(lat) * cos(lon);
|
|
float y2 = radius * cos(lat) * sin(lon);
|
|
float z2 = radius * sin(lat);
|
|
|
|
// lat += lat_delta_angle;
|
|
lon += lon_delta_angle;
|
|
|
|
float x3 = radius * cos(lat) * cos(lon);
|
|
float y3 = radius * cos(lat) * sin(lon);
|
|
float z3 = radius * sin(lat);
|
|
|
|
lat -= lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x4 = radius * cos(lat) * cos(lon);
|
|
float y4 = radius * cos(lat) * sin(lon);
|
|
float z4 = radius * sin(lat);
|
|
|
|
float tex_x = lonn / lonc;
|
|
float tex_y = latn / latc;
|
|
|
|
// std::cout << x1 << " " << y1 << " " << z1 << " " << x2 << " " << y2 << " " << z2 << std::endl;
|
|
|
|
earthSphere.addRect(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4,
|
|
|
|
tex_x, tex_y, tex_x, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y);
|
|
}
|
|
}
|
|
|
|
/*addRect(-1, -1, 0,
|
|
-1, 1, 0,
|
|
1, 1, 0,
|
|
1, -1, 0,
|
|
1, 1,
|
|
1, 0,
|
|
0, 0,
|
|
0, 1);*/
|
|
|
|
// float r = 0.5;
|
|
// for (float val = 0; val = M_PI * 2; val++)
|
|
//{
|
|
// }
|
|
|
|
/*
|
|
float x = -1.2;
|
|
|
|
float chunks = 50;
|
|
float delta_angle = (M_PI * 2) / chunks;
|
|
|
|
float delta_text = 1.0 / chunks;
|
|
|
|
for (float i = 0; i < M_PI * 2; i += delta_angle)
|
|
{
|
|
float tx = 1.0f * (i / (M_PI * 2));
|
|
|
|
float angle1 = i;
|
|
float x1 = 0.5 * sin(angle1);
|
|
float z1 = 0.5 * cos(angle1);
|
|
|
|
float angle2 = i + delta_angle;
|
|
float x2 = 0.5 * sin(angle2);
|
|
float z2 = 0.5 * cos(angle2);
|
|
|
|
addRect(x1, -1, z1,
|
|
x1, 0, z1,
|
|
x2, 0, z2,
|
|
x2, -1, z2,
|
|
|
|
tx, 0,
|
|
tx, 1,
|
|
tx + delta_text, 1,
|
|
tx + delta_text, 0);
|
|
|
|
//x += 0.6;
|
|
}*/
|
|
|
|
/*
|
|
addRect(-1, -1, 0,
|
|
-1, 0, 0,
|
|
1, 0, 0,
|
|
1, -1, 0,
|
|
|
|
0, 0,
|
|
0, 0.5,
|
|
1, 0.5,
|
|
1, 0);
|
|
|
|
addRect(-1, 0, 0,
|
|
-1, 1, 0,
|
|
1, 1, 0,
|
|
1, 0, 0,
|
|
|
|
0, 0.5,
|
|
0, 1,
|
|
1, 1,
|
|
1, 0.5);
|
|
*/
|
|
}
|
|
|
|
{
|
|
image::Image map_image;
|
|
// map_image.load_jpeg(resources::getResourcePath("maps/nasa.jpg"));
|
|
// map_image.load_jpeg("/home/alan/Downloads/land_ocean_ice_cloud_2048.jpg");
|
|
image::load_img(map_image, resources::getResourcePath("maps/map_ne2.jpg")); // "/home/alan/Downloads/world.200408.3x21600x10800.png");
|
|
// map_image.load_png("/home/alan/Downloads/projection_ews_test.png");
|
|
// map_image.load_jpeg("/home/alan/Downloads/dnb_land_ocean_ice.2012.54000x27000_geo.jpg");
|
|
// map_image.load_png("/home/alan/Downloads/projection_metop.png");
|
|
Texture = makeImageTexture();
|
|
uint32_t *map_texture_buff = new uint32_t[map_image.width() * map_image.height()];
|
|
image::image_to_rgba(map_image, map_texture_buff);
|
|
// uchar_to_rgba(map_image.raw_data(), map_texture_buff, map_image.width() * map_image.height(), 3);
|
|
updateImageTexture(Texture, map_texture_buff, map_image.width(), map_image.height());
|
|
delete[] map_texture_buff;
|
|
}
|
|
|
|
{
|
|
image::Image map_image(8, 2, 2, 3);
|
|
map_image.fill_color({1, 0, 0});
|
|
Texture2 = makeImageTexture();
|
|
uint32_t *map_texture_buff = new uint32_t[map_image.width() * map_image.height()];
|
|
image::image_to_rgba(map_image, map_texture_buff);
|
|
// uchar_to_rgba(map_image.raw_data(), map_texture_buff, map_image.width() * map_image.height(), 3);
|
|
updateImageTexture(Texture2, map_texture_buff, map_image.width(), map_image.height());
|
|
delete[] map_texture_buff;
|
|
}
|
|
|
|
{
|
|
image::Image map_image(8, 2, 2, 3);
|
|
map_image.fill_color({0, 0, 1});
|
|
Texture3 = makeImageTexture();
|
|
uint32_t *map_texture_buff = new uint32_t[map_image.width() * map_image.height()];
|
|
image::image_to_rgba(map_image, map_texture_buff);
|
|
// uchar_to_rgba(map_image.raw_data(), map_texture_buff, map_image.width() * map_image.height(), 3);
|
|
updateImageTexture(Texture3, map_texture_buff, map_image.width(), map_image.height());
|
|
delete[] map_texture_buff;
|
|
}
|
|
|
|
// Use our shader
|
|
// glUseProgram(program);
|
|
|
|
glGenBuffers(1, &earthSphere.vertexbuffer);
|
|
glBindBuffer(GL_ARRAY_BUFFER, earthSphere.vertexbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * earthSphere.vertices_buf.size(), earthSphere.vertices_buf.data(), GL_STATIC_DRAW);
|
|
|
|
glGenBuffers(1, &earthSphere.uvbuffer);
|
|
glBindBuffer(GL_ARRAY_BUFFER, earthSphere.uvbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * earthSphere.textpos_buf.size(), earthSphere.textpos_buf.data(), GL_STATIC_DRAW);
|
|
|
|
// The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.
|
|
glGenFramebuffers(1, &FramebufferName);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
|
|
|
|
// The texture we're going to render to
|
|
glGenTextures(1, &renderedTexture);
|
|
|
|
// "Bind" the newly created texture : all future texture functions will modify this texture
|
|
glBindTexture(GL_TEXTURE_2D, renderedTexture);
|
|
|
|
// Give an empty image to OpenGL ( the last "0" )
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, render_width, render_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
|
|
|
// Poor filtering. Needed !
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
|
// The depth buffer
|
|
glGenRenderbuffers(1, &depthrenderbuffer);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, render_width, render_height);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer);
|
|
|
|
// Set "renderedTexture" as our colour attachement #0
|
|
// glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
|
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderedTexture, 0);
|
|
|
|
// Set the list of draw buffers.
|
|
GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
|
|
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
|
|
|
|
// Always check that our framebuffer is ok
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
|
logger->error("ERROR");
|
|
|
|
glGenVertexArrays(1, &VertexArrayID);
|
|
glBindVertexArray(VertexArrayID);
|
|
|
|
std::string vertex = "#version 330 core\n"
|
|
"layout(location = 0) in vec3 vertexPosition_modelspace;"
|
|
"layout(location = 1) in vec2 vertexUV;"
|
|
"out vec2 UV;"
|
|
"uniform mat4 MVP;"
|
|
"void main(){"
|
|
"gl_Position = MVP * vec4(vertexPosition_modelspace,1);"
|
|
//"gl_Position.xyz.y = 1.0 - gl_Position.xyz.y;"
|
|
"UV = vertexUV;"
|
|
"}";
|
|
|
|
std::string fragment = "#version 330 core\n"
|
|
"in vec2 UV;"
|
|
"out vec3 color;"
|
|
"uniform sampler2D myTextureSampler;"
|
|
"void main(){"
|
|
"color = texture2D( myTextureSampler, UV ).rgb;"
|
|
"}";
|
|
|
|
program = compileShaders(vertex, fragment);
|
|
|
|
MatrixID = glGetUniformLocation(program, "MVP");
|
|
TextureID = glGetUniformLocation(program, "myTextureSampler");
|
|
|
|
Projection = glm::perspective(glm::radians(45.0f), 16.0f / 9.0f, 0.1f, 100.0f);
|
|
// Camera matrix
|
|
View = glm::lookAt(glm::vec3(0, 0, 2), // Camera is at (4,3,3), in World Space
|
|
glm::vec3(0, 0, 0), // and looks at the origin
|
|
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
|
|
);
|
|
// Model matrix : an identity matrix (model will be at the origin)
|
|
Model = glm::mat4(1.0f);
|
|
// glm::vec3 vv(1, 0, 0);
|
|
Model = glm::rotate<float>(Model, (M_PI / 2) * 3, glm::vec3(1, 0, 0)); // where x, y, z is axis of rotation (e.g. 0 1 0)
|
|
Model = glm::rotate<float>(Model, (M_PI / 2) * 1, glm::vec3(0, 0, 1));
|
|
|
|
// Enable depth test
|
|
// glEnable(GL_DEPTH_TEST);
|
|
// Accept fragment if it closer to the camera than the former one
|
|
// glDepthFunc(GL_LESS);
|
|
|
|
// METEOR
|
|
glGenBuffers(1, &meteorSphere.vertexbuffer);
|
|
glGenBuffers(1, &meteorSphere.uvbuffer);
|
|
|
|
// NOAA
|
|
glGenBuffers(1, &noaaSphere.vertexbuffer);
|
|
glGenBuffers(1, &noaaSphere.uvbuffer);
|
|
}
|
|
// int t = 0;
|
|
// float view_x = 4;
|
|
// float view_y = 3;
|
|
// float view_z = 3;
|
|
|
|
// Initial position : on +Z
|
|
glm::vec3 position = glm::vec3(0, 0, 5);
|
|
// Initial horizontal angle : toward -Z
|
|
float horizontalAngle = 3.14f;
|
|
// Initial vertical angle : none
|
|
float verticalAngle = 0.0f;
|
|
// Initial Field of View
|
|
float initialFoV = 45.0f;
|
|
|
|
float speed = 3.f; // 3 units / second
|
|
float mouseSpeed = 0.001f;
|
|
|
|
GLuint draw(GLFWwindow *window, int render_widthf, int render_heightf)
|
|
{
|
|
Projection = glm::perspective(glm::radians(45.0f), float(render_widthf) / float(render_heightf), 0.1f, 100.0f); // Update aspect ratio
|
|
// if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
|
// view_z += 0.1;
|
|
// if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
|
// view_z -= 0.1;
|
|
|
|
// if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
|
// view_x += 0.1;
|
|
// if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
|
// view_x -= 0.1;
|
|
|
|
// if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
|
// view_y += 0.1;
|
|
// if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
|
// view_y -= 0.1;
|
|
|
|
{
|
|
static double lastTime = glfwGetTime();
|
|
|
|
// Compute time difference between current and last frame
|
|
double currentTime = glfwGetTime();
|
|
float deltaTime = float(currentTime - lastTime);
|
|
|
|
// // Get mouse position
|
|
// double xpos, ypos;
|
|
// glfwGetCursorPos(window, &xpos, &ypos);
|
|
|
|
// Reset mouse position for next frame
|
|
// glfwSetCursorPos(window, 1024 / 2, 768 / 2);
|
|
|
|
// // Compute new orientation
|
|
// horizontalAngle += mouseSpeed * float(1024 / 2 - xpos);
|
|
// verticalAngle += mouseSpeed * float(768 / 2 - ypos);
|
|
|
|
// auto mousedrag = ImGui::GetMouseDragDelta(ImGuiMouseButton_Left);
|
|
|
|
// Compute new orientation
|
|
// horizontalAngle += mouseSpeed * mousedrag.x;
|
|
// verticalAngle += mouseSpeed * mousedrag.y;
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
|
verticalAngle += mouseSpeed * -10;
|
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
|
verticalAngle += mouseSpeed * 10;
|
|
|
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
|
horizontalAngle += mouseSpeed * -10;
|
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
|
horizontalAngle += mouseSpeed * 10;
|
|
|
|
if (verticalAngle > M_PI / 2)
|
|
verticalAngle = M_PI / 2;
|
|
else if (verticalAngle < -M_PI / 2)
|
|
verticalAngle = -M_PI / 2;
|
|
|
|
#if 1
|
|
// Direction : Spherical coordinates to Cartesian coordinates conversion
|
|
glm::vec3 direction(cos(verticalAngle) * sin(horizontalAngle), sin(verticalAngle), cos(verticalAngle) * cos(horizontalAngle));
|
|
|
|
auto dir2 = direction;
|
|
dir2.y = 0;
|
|
|
|
// Right vector
|
|
glm::vec3 right = glm::vec3(sin(horizontalAngle - 3.14f / 2.0f), 0, cos(horizontalAngle - 3.14f / 2.0f));
|
|
|
|
// Up vector
|
|
glm::vec3 up = glm::cross(right, direction);
|
|
|
|
// Move forward
|
|
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
|
{
|
|
position.y -= deltaTime * speed;
|
|
}
|
|
// Move backward
|
|
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
|
{
|
|
position.y += deltaTime * speed;
|
|
}
|
|
// Move up
|
|
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
|
{
|
|
position += dir2 * deltaTime * speed;
|
|
}
|
|
// Move down
|
|
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
|
{
|
|
position -= dir2 * deltaTime * speed;
|
|
}
|
|
// Strafe right
|
|
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
|
{
|
|
position += right * deltaTime * speed;
|
|
}
|
|
// Strafe left
|
|
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
|
{
|
|
position -= right * deltaTime * speed;
|
|
}
|
|
|
|
// Projection = glm::perspective(glm::radians(45), 4.0f / 3.0f, 0.1f, 100.0f);
|
|
|
|
View = glm::lookAt(position, // Camera is here
|
|
position + direction, // and looks here : at the same position, plus "direction"
|
|
up // Head is up (set to 0,-1,0 to look upside-down)
|
|
);
|
|
#else
|
|
// Direction : Spherical coordinates to Cartesian coordinates conversion
|
|
glm::vec3 direction(cos(verticalAngle) * sin(horizontalAngle), sin(verticalAngle), cos(verticalAngle) * cos(horizontalAngle));
|
|
|
|
// Right vector
|
|
glm::vec3 right = glm::vec3(sin(horizontalAngle - 3.14f / 2.0f), 0, cos(horizontalAngle - 3.14f / 2.0f));
|
|
|
|
// Up vector
|
|
glm::vec3 up = glm::cross(right, direction);
|
|
|
|
// Move forward
|
|
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
|
{
|
|
position += direction * deltaTime * speed;
|
|
}
|
|
// Move backward
|
|
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
|
|
{
|
|
position -= direction * deltaTime * speed;
|
|
}
|
|
// Move up
|
|
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS)
|
|
{
|
|
position += up * deltaTime * speed;
|
|
}
|
|
// Move down
|
|
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
|
|
{
|
|
position -= up * deltaTime * speed;
|
|
}
|
|
// Strafe right
|
|
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS)
|
|
{
|
|
position += right * deltaTime * speed;
|
|
}
|
|
// Strafe left
|
|
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS)
|
|
{
|
|
position -= right * deltaTime * speed;
|
|
}
|
|
|
|
// Projection = glm::perspective(glm::radians(45), 4.0f / 3.0f, 0.1f, 100.0f);
|
|
|
|
View = glm::lookAt(position, // Camera is here
|
|
position + direction, // and looks here : at the same position, plus "direction"
|
|
up // Head is up (set to 0,-1,0 to look upside-down)
|
|
);
|
|
#endif
|
|
|
|
// For the next frame, the "last time" will be "now"
|
|
lastTime = currentTime;
|
|
}
|
|
|
|
// View = glm::lookAt(
|
|
// glm::vec3(view_x, view_y, view_z), // Camera is at (4,3,3), in World Space
|
|
// glm::vec3(0, 0, 0), // and looks at the origin
|
|
// glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
|
|
//);
|
|
|
|
// Render to our framebuffer
|
|
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
|
|
glViewport(0, 0, render_width, render_height); // Render on the whole framebuffer, complete from the lower left corner to the upper right
|
|
|
|
MVP = Projection * View * Model;
|
|
|
|
// Dark blue background
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
// Enable depth test
|
|
glEnable(GL_DEPTH_TEST);
|
|
// Accept fragment if it closer to the camera than the former one
|
|
glDepthFunc(GL_LESS);
|
|
|
|
// Use our shader
|
|
glUseProgram(program);
|
|
|
|
// Send our transformation to the currently bound shader,
|
|
// in the "MVP" uniform
|
|
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
|
|
|
|
{
|
|
// Bind our texture in Texture Unit 0
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, Texture);
|
|
// Set our "myTextureSampler" sampler to use Texture Unit 0
|
|
glUniform1i(TextureID, 0);
|
|
|
|
// 1rst attribute buffer : vertices
|
|
glEnableVertexAttribArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, earthSphere.vertexbuffer);
|
|
glVertexAttribPointer(0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
|
3, // size
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// 2nd attribute buffer : UVs
|
|
glEnableVertexAttribArray(1);
|
|
glBindBuffer(GL_ARRAY_BUFFER, earthSphere.uvbuffer);
|
|
glVertexAttribPointer(1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
|
2, // size : U+V => 2
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// Draw the triangle !
|
|
glDrawArrays(GL_TRIANGLES, 0, earthSphere.vertices_buf.size()); // 3 indices starting at 0 -> 1 triangle
|
|
|
|
glDisableVertexAttribArray(0);
|
|
}
|
|
|
|
{
|
|
double utc_time = satdump::getTime();
|
|
predict_orbit(satellite_object, &satellite_orbit, predict_to_julian_double(utc_time));
|
|
|
|
geodetic::vector vpos;
|
|
geodetic::lla2xyz(geodetic::geodetic_coords_t(satellite_orbit.latitude, satellite_orbit.longitude, satellite_orbit.altitude, true), vpos);
|
|
|
|
meteorSphere.textpos_buf.clear();
|
|
meteorSphere.vertices_buf.clear();
|
|
|
|
double x = -(vpos.x) * 5 / 6371.0;
|
|
double y = -(vpos.y) * 5 / 6371.0;
|
|
double z = -(vpos.z) * 5 / 6371.0;
|
|
|
|
// Original
|
|
{
|
|
float latc = 50;
|
|
float lonc = latc * 2; // 100;
|
|
float radius = 0.1;
|
|
|
|
float lat_delta_angle = (M_PI) / latc;
|
|
float lon_delta_angle = (M_PI * 2) / lonc;
|
|
|
|
float lat_text_delta = 1.0f / latc;
|
|
float lon_text_delta = 1.0f / lonc;
|
|
|
|
for (float latn = 0; latn < latc; latn++) // The poles are made from triangles... Skip them
|
|
{
|
|
for (float lonn = 0; lonn < lonc; lonn++)
|
|
{
|
|
float lat = (latn - (latc / 2)) * lat_delta_angle;
|
|
float lon = lonn * lon_delta_angle;
|
|
|
|
float x1 = radius * cos(lat) * cos(lon) + x;
|
|
float y1 = radius * cos(lat) * sin(lon) + y;
|
|
float z1 = radius * sin(lat) + z;
|
|
|
|
lat += lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x2 = radius * cos(lat) * cos(lon) + x;
|
|
float y2 = radius * cos(lat) * sin(lon) + y;
|
|
float z2 = radius * sin(lat) + z;
|
|
|
|
// lat += lat_delta_angle;
|
|
lon += lon_delta_angle;
|
|
|
|
float x3 = radius * cos(lat) * cos(lon) + x;
|
|
float y3 = radius * cos(lat) * sin(lon) + y;
|
|
float z3 = radius * sin(lat) + z;
|
|
|
|
lat -= lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x4 = radius * cos(lat) * cos(lon) + x;
|
|
float y4 = radius * cos(lat) * sin(lon) + y;
|
|
float z4 = radius * sin(lat) + z;
|
|
|
|
float tex_x = lonn / lonc;
|
|
float tex_y = latn / latc;
|
|
|
|
// std::cout << x1 << " " << y1 << " " << z1 << " " << x2 << " " << y2 << " " << z2 << std::endl;
|
|
|
|
meteorSphere.addRect(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4,
|
|
|
|
tex_x, tex_y, tex_x, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y);
|
|
}
|
|
}
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, meteorSphere.vertexbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * meteorSphere.vertices_buf.size(), meteorSphere.vertices_buf.data(), GL_STATIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, meteorSphere.uvbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * meteorSphere.textpos_buf.size(), meteorSphere.textpos_buf.data(), GL_STATIC_DRAW);
|
|
|
|
{
|
|
// Bind our texture in Texture Unit 0
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, Texture2);
|
|
// Set our "myTextureSampler" sampler to use Texture Unit 0
|
|
glUniform1i(TextureID, 0);
|
|
|
|
// 1rst attribute buffer : vertices
|
|
glEnableVertexAttribArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, meteorSphere.vertexbuffer);
|
|
glVertexAttribPointer(0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
|
3, // size
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// 2nd attribute buffer : UVs
|
|
glEnableVertexAttribArray(1);
|
|
glBindBuffer(GL_ARRAY_BUFFER, meteorSphere.uvbuffer);
|
|
glVertexAttribPointer(1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
|
2, // size : U+V => 2
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// Draw the triangle !
|
|
glDrawArrays(GL_TRIANGLES, 0, meteorSphere.vertices_buf.size()); // 3 indices starting at 0 -> 1 triangle
|
|
|
|
glDisableVertexAttribArray(0);
|
|
}
|
|
}
|
|
|
|
{
|
|
double utc_time = satdump::getTime();
|
|
predict_orbit(satellite_object2, &satellite_orbit2, predict_to_julian_double(utc_time));
|
|
|
|
geodetic::vector vpos;
|
|
geodetic::lla2xyz(geodetic::geodetic_coords_t(satellite_orbit2.latitude, satellite_orbit2.longitude, satellite_orbit2.altitude, true), vpos);
|
|
|
|
noaaSphere.textpos_buf.clear();
|
|
noaaSphere.vertices_buf.clear();
|
|
|
|
double x = -(vpos.x) * 5 / 6371.0;
|
|
double y = -(vpos.y) * 5 / 6371.0;
|
|
double z = -(vpos.z) * 5 / 6371.0;
|
|
|
|
// Original
|
|
{
|
|
float latc = 50;
|
|
float lonc = latc * 2; // 100;
|
|
float radius = 0.1;
|
|
|
|
float lat_delta_angle = (M_PI) / latc;
|
|
float lon_delta_angle = (M_PI * 2) / lonc;
|
|
|
|
float lat_text_delta = 1.0f / latc;
|
|
float lon_text_delta = 1.0f / lonc;
|
|
|
|
for (float latn = 0; latn < latc; latn++) // The poles are made from triangles... Skip them
|
|
{
|
|
for (float lonn = 0; lonn < lonc; lonn++)
|
|
{
|
|
float lat = (latn - (latc / 2)) * lat_delta_angle;
|
|
float lon = lonn * lon_delta_angle;
|
|
|
|
float x1 = radius * cos(lat) * cos(lon) + x;
|
|
float y1 = radius * cos(lat) * sin(lon) + y;
|
|
float z1 = radius * sin(lat) + z;
|
|
|
|
lat += lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x2 = radius * cos(lat) * cos(lon) + x;
|
|
float y2 = radius * cos(lat) * sin(lon) + y;
|
|
float z2 = radius * sin(lat) + z;
|
|
|
|
// lat += lat_delta_angle;
|
|
lon += lon_delta_angle;
|
|
|
|
float x3 = radius * cos(lat) * cos(lon) + x;
|
|
float y3 = radius * cos(lat) * sin(lon) + y;
|
|
float z3 = radius * sin(lat) + z;
|
|
|
|
lat -= lat_delta_angle;
|
|
// lon += lon_delta_angle;
|
|
|
|
float x4 = radius * cos(lat) * cos(lon) + x;
|
|
float y4 = radius * cos(lat) * sin(lon) + y;
|
|
float z4 = radius * sin(lat) + z;
|
|
|
|
float tex_x = lonn / lonc;
|
|
float tex_y = latn / latc;
|
|
|
|
// std::cout << x1 << " " << y1 << " " << z1 << " " << x2 << " " << y2 << " " << z2 << std::endl;
|
|
|
|
noaaSphere.addRect(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4,
|
|
|
|
tex_x, tex_y, tex_x, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y + lat_text_delta, tex_x + lon_text_delta, tex_y);
|
|
}
|
|
}
|
|
}
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, noaaSphere.vertexbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * noaaSphere.vertices_buf.size(), noaaSphere.vertices_buf.data(), GL_STATIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, noaaSphere.uvbuffer);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * noaaSphere.textpos_buf.size(), noaaSphere.textpos_buf.data(), GL_STATIC_DRAW);
|
|
|
|
{
|
|
// Bind our texture in Texture Unit 0
|
|
glActiveTexture(GL_TEXTURE0);
|
|
glBindTexture(GL_TEXTURE_2D, Texture3);
|
|
// Set our "myTextureSampler" sampler to use Texture Unit 0
|
|
glUniform1i(TextureID, 0);
|
|
|
|
// 1rst attribute buffer : vertices
|
|
glEnableVertexAttribArray(0);
|
|
glBindBuffer(GL_ARRAY_BUFFER, noaaSphere.vertexbuffer);
|
|
glVertexAttribPointer(0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
|
|
3, // size
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// 2nd attribute buffer : UVs
|
|
glEnableVertexAttribArray(1);
|
|
glBindBuffer(GL_ARRAY_BUFFER, noaaSphere.uvbuffer);
|
|
glVertexAttribPointer(1, // attribute. No particular reason for 1, but must match the layout in the shader.
|
|
2, // size : U+V => 2
|
|
GL_FLOAT, // type
|
|
GL_FALSE, // normalized?
|
|
0, // stride
|
|
(void *)0 // array buffer offset
|
|
);
|
|
|
|
// Draw the triangle !
|
|
glDrawArrays(GL_TRIANGLES, 0, noaaSphere.vertices_buf.size()); // 3 indices starting at 0 -> 1 triangle
|
|
|
|
glDisableVertexAttribArray(0);
|
|
}
|
|
}
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
|
return renderedTexture;
|
|
}
|
|
|
|
GLuint compileShaders(std::string vertex_src, std::string fragment_src)
|
|
{
|
|
GLint Result;
|
|
GLint InfoLogLength;
|
|
|
|
// Create the shaders
|
|
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
// Compile Vertex Shader
|
|
const char *vsrc = vertex_src.c_str();
|
|
glShaderSource(VertexShaderID, 1, &vsrc, NULL);
|
|
glCompileShader(VertexShaderID);
|
|
|
|
// Check Vertex Shader
|
|
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
|
|
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if (InfoLogLength > 0)
|
|
{
|
|
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
|
|
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
|
|
printf("%s\n", &VertexShaderErrorMessage[0]);
|
|
}
|
|
|
|
// Compile Fragment Shader
|
|
const char *fsrc = fragment_src.c_str();
|
|
glShaderSource(FragmentShaderID, 1, &fsrc, NULL);
|
|
glCompileShader(FragmentShaderID);
|
|
|
|
// Check Fragment Shader
|
|
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
|
|
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if (InfoLogLength > 0)
|
|
{
|
|
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
|
|
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
|
|
printf("%s\n", &FragmentShaderErrorMessage[0]);
|
|
}
|
|
|
|
// Link the program
|
|
printf("Linking program\n");
|
|
GLuint ProgramID = glCreateProgram();
|
|
glAttachShader(ProgramID, VertexShaderID);
|
|
glAttachShader(ProgramID, FragmentShaderID);
|
|
glLinkProgram(ProgramID);
|
|
|
|
// Check the program
|
|
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
|
|
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
|
|
if (InfoLogLength > 0)
|
|
{
|
|
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
|
|
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
|
|
printf("%s\n", &ProgramErrorMessage[0]);
|
|
}
|
|
|
|
glDetachShader(ProgramID, VertexShaderID);
|
|
glDetachShader(ProgramID, FragmentShaderID);
|
|
|
|
glDeleteShader(VertexShaderID);
|
|
glDeleteShader(FragmentShaderID);
|
|
|
|
printf("Done\n");
|
|
|
|
return ProgramID;
|
|
}
|
|
}; |