diff --git a/.env b/.env new file mode 100644 index 0000000..88a2a2c --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +WEATHER_API_KEY=b5337f9628db3b0949f914f3864834b4 +LOCAL=Lisbond diff --git a/imgui.ini b/imgui.ini new file mode 100644 index 0000000..f668319 --- /dev/null +++ b/imgui.ini @@ -0,0 +1,20 @@ +[Window][Debug##Default] +Pos=60,60 +Size=400,400 + +[Window][API Key Status] +Pos=60,60 +Size=201,51 + +[Window][Status] +Pos=24,27 +Size=234,142 + +[Window][Debug Window] +Pos=23,27 +Size=370,226 + +[Window][Weather Data] +Pos=30,266 +Size=862,225 + diff --git a/include/http_get.c b/include/http_get.c new file mode 100644 index 0000000..206c0a8 --- /dev/null +++ b/include/http_get.c @@ -0,0 +1,54 @@ +#include "http_get.h" + +// Callback for libcurl to write response into our struct +static size_t write_callback(void *data, size_t size, size_t nmemb, void *userp) { + size_t realsize = size * nmemb; + struct Memory *mem = (struct Memory *)userp; + + char *ptr = realloc(mem->response, mem->size + realsize + 1); + if(ptr == NULL) { + // Out of memory! + fprintf(stderr, "realloc() failed\n"); + return 0; + } + + mem->response = ptr; + memcpy(&(mem->response[mem->size]), data, realsize); + mem->size += realsize; + mem->response[mem->size] = '\0'; + return realsize; +} + +// Function: GET request, returns heap string (caller must free) +char *http_get(const char *url) { + CURL *curl; + CURLcode res; + struct Memory chunk; + + chunk.response = malloc(1); // start with empty buffer + chunk.size = 0; + + curl_global_init(CURL_GLOBAL_ALL); + curl = curl_easy_init(); + + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // follow redirects + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); + + res = curl_easy_perform(curl); + + if(res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + free(chunk.response); + chunk.response = NULL; + } + + curl_easy_cleanup(curl); + } + + curl_global_cleanup(); + return chunk.response; +} + diff --git a/include/http_get.h b/include/http_get.h new file mode 100644 index 0000000..07bba8d --- /dev/null +++ b/include/http_get.h @@ -0,0 +1,29 @@ +#ifndef HTTP_GET_H +#define HTTP_GET_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// Struct to hold response data +struct Memory { + char *response; + size_t size; +}; + +// Callback for libcurl to write response into our struct +static size_t write_callback(void *data, size_t size, size_t nmemb, void *userp); + +// Function: GET request, returns heap string (caller must free) +char *http_get(const char *url); + +#ifdef __cplusplus +} +#endif + +#endif // HTTP_GET_H diff --git a/source/main.cpp b/source/main.cpp index 0269c5e..42819b6 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,12 +1,12 @@ -#include #include +#include #include #include #include // glad and GLFW -#include #include +#include // glm math #include @@ -24,179 +24,168 @@ const float SCR_WIDTH = 1200.0f; const float SCR_HEIGHT = 1200.0f; int main(void) { - // Initialize GLFW - if (!glfwInit()) return -1; + // Initialize GLFW + if (!glfwInit()) + return -1; - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // REQUIRED on macOS - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_SAMPLES, 8); // 8x MSAA + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // REQUIRED on macOS + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_SAMPLES, 8); // 8x MSAA - GLFWwindow* window = glfwCreateWindow((int)SCR_WIDTH, (int)SCR_HEIGHT, "RASTER", nullptr, nullptr); - if (!window) { - glfwTerminate(); - return -1; - } - glfwMakeContextCurrent(window); + GLFWwindow *window = glfwCreateWindow((int)SCR_WIDTH, (int)SCR_HEIGHT, "RASTER", nullptr, nullptr); + if (!window) { + glfwTerminate(); + return -1; + } + glfwMakeContextCurrent(window); - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - std::cerr << "Failed to initialize GLAD\n"; - return -1; - } + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + std::cerr << "Failed to initialize GLAD\n"; + return -1; + } - glViewport(0, 0, (int)SCR_WIDTH, (int)SCR_HEIGHT); + glViewport(0, 0, (int)SCR_WIDTH, (int)SCR_HEIGHT); - //DEBUG - std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; + // DEBUG + std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; - // ERROR: macOS does not support compute shaders in OpenGL < 4.3. - // GLuint computeProgram = createComputeProgram(COMPUTE_FILE); + // ERROR: macOS does not support compute shaders in OpenGL < 4.3. + // GLuint computeProgram = createComputeProgram(COMPUTE_FILE); - // ----- Vertex Data ----- - // Cube - // Positions - float vertices[] = { - // positions - -1.0f, -1.0f, 0.0f, - 1.0f, -1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 0.0f - }; + // ----- Vertex Data ----- + // Cube + // Positions + float vertices[] = {// positions + -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f}; - unsigned int indices[] = { - 0, 1, 2, - 2, 3, 0 - }; + unsigned int indices[] = {0, 1, 2, 2, 3, 0}; - GLuint VAO, VBO, EBO; - glGenVertexArrays(1,&VAO); - glGenBuffers(1,&VBO); - glGenBuffers(1,&EBO); + GLuint VAO, VBO, EBO; + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); - glBindVertexArray(VAO); + glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER,VBO); - glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - // position - VERTEX SHADER - glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)0); - glEnableVertexAttribArray(0); + // position - VERTEX SHADER + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0); + glEnableVertexAttribArray(0); - // color - FRAGMENT SHADER - glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void*)(3*sizeof(float))); - glEnableVertexAttribArray(1); + // color - FRAGMENT SHADER + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)(3 * sizeof(float))); + glEnableVertexAttribArray(1); - glBindBuffer(GL_ARRAY_BUFFER,0); - // glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + // glBindVertexArray(0); - // Load shaders - GLuint shaderProgram = createShaderProgram(VERTEX_FILE, FRAGMENT_FILE); + // Load shaders + GLuint shaderProgram = createShaderProgram(VERTEX_FILE, FRAGMENT_FILE); - // Check if shader program was created successfully - if (shaderProgram == 0) { - std::cerr << "Failed to create shader programs.\n"; - return -1; - } + // Check if shader program was created successfully + if (shaderProgram == 0) { + std::cerr << "Failed to create shader programs.\n"; + return -1; + } - // Caulculate model, view, projection matrices - glm::mat4 model = glm::mat4(1.0f); - glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -1.0f)); - glm::mat4 projection = glm::perspective(glm::radians(45.0f), (SCR_WIDTH/SCR_HEIGHT)*2, 0.1f, 100.0f); + // Caulculate model, view, projection matrices + glm::mat4 model = glm::mat4(1.0f); + glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -1.0f)); + glm::mat4 projection = glm::perspective(glm::radians(45.0f), (SCR_WIDTH / SCR_HEIGHT) * 2, 0.1f, 100.0f); - GLuint modelLoc = (unsigned int) glGetUniformLocation(shaderProgram, "model"); - GLuint viewLoc = (unsigned int) glGetUniformLocation(shaderProgram, "view"); - GLuint projLoc = (unsigned int) glGetUniformLocation(shaderProgram, "projection"); + GLuint modelLoc = (unsigned int)glGetUniformLocation(shaderProgram, "model"); + GLuint viewLoc = (unsigned int)glGetUniformLocation(shaderProgram, "view"); + GLuint projLoc = (unsigned int)glGetUniformLocation(shaderProgram, "projection"); - glUseProgram(shaderProgram); - glUniformMatrix4fv((int) modelLoc, 1, GL_FALSE, glm::value_ptr(model)); - glUniformMatrix4fv((int) viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - glUniformMatrix4fv((int) projLoc, 1, GL_FALSE, glm::value_ptr(projection)); + glUseProgram(shaderProgram); + glUniformMatrix4fv((int)modelLoc, 1, GL_FALSE, glm::value_ptr(model)); + glUniformMatrix4fv((int)viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + glUniformMatrix4fv((int)projLoc, 1, GL_FALSE, glm::value_ptr(projection)); + GLint resLoc = glGetUniformLocation(shaderProgram, "u_resolution"); + glUniform2f(resLoc, SCR_WIDTH, SCR_HEIGHT); // hardcode for now - GLint resLoc = glGetUniformLocation(shaderProgram, "u_resolution"); - glUniform2f(resLoc, SCR_WIDTH, SCR_HEIGHT); // hardcode for now + GLint timeLoc = glGetUniformLocation(shaderProgram, "u_time"); + GLint scaleLoc = glGetUniformLocation(shaderProgram, "u_scale"); + GLint mouseLoc = glGetUniformLocation(shaderProgram, "u_mouse"); - GLint timeLoc = glGetUniformLocation(shaderProgram, "u_time"); - GLint scaleLoc = glGetUniformLocation(shaderProgram, "u_scale"); - GLint mouseLoc = glGetUniformLocation(shaderProgram, "u_mouse"); + glEnable(GL_MULTISAMPLE); - glEnable(GL_MULTISAMPLE); + float scale = 1.0f; + int frameCount = 0; + float mousePos[2] = {0.0f, 0.0f}; - float scale = 1.0f; - int frameCount = 0; - float mousePos[2] = {0.0f, 0.0f}; + // FPS tracking + double lastTime = glfwGetTime(); // when we last printed FPS + double fps = 0.0; - // FPS tracking - double lastTime = glfwGetTime(); // when we last printed FPS - double fps = 0.0; + // Render loop + while (!glfwWindowShouldClose(window)) { + float timeValue = (float)glfwGetTime(); + double xpos, ypos; - // Render loop - while (!glfwWindowShouldClose(window)) { - float timeValue = (float)glfwGetTime(); - double xpos, ypos; + // Get mouse positions + glfwGetCursorPos(window, &xpos, &ypos); + mousePos[0] = (float)xpos; + mousePos[1] = (float)(SCR_HEIGHT - ypos); // Invert y-axis for OpenGL coordinates - // Get mouse positions - glfwGetCursorPos(window, &xpos, &ypos); - mousePos[0] = (float)xpos; - mousePos[1] = (float)(SCR_HEIGHT - ypos); // Invert y-axis for OpenGL coordinates + // Input + glfwPollEvents(); - // Input - glfwPollEvents(); + // Scroll to zoom in/out + if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { + scale += 0.01f; + if (scale > 10.0f) + scale = 10.0f; // Max zoom + } - // Scroll to zoom in/out - if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { - scale += 0.01f; - if (scale > 10.0f) scale = 10.0f; // Max zoom - } + if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { + scale -= 0.01f; + if (scale < 0.1f) + scale = 0.1f; // Min zoom + } - if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { - scale -= 0.01f; - if (scale < 0.1f) scale = 0.1f; // Min zoom - } + // --- FPS Counter --- + double currentTime = glfwGetTime(); + double delta = currentTime - lastTime; - // --- FPS Counter --- - double currentTime = glfwGetTime(); - double delta = currentTime - lastTime; + if (delta >= 1.0) { // print every ~1 second + fps = double(frameCount) / delta; + std::cout << "FPS: " << fps << " Time: " << timeValue << " Scale: " << scale << " Mouse: (" << mousePos[0] << ", " << mousePos[1] << ")" << std::endl; - if (delta >= 1.0) { // print every ~1 second - fps = double(frameCount) / delta; - std::cout << "FPS: " << fps - << " Time: " << timeValue - << " Scale: " << scale - << " Mouse: (" << mousePos[0] << ", " << mousePos[1] << ")" - << std::endl; + frameCount = 0; + lastTime = currentTime; + } - frameCount = 0; - lastTime = currentTime; - } + glUniform1f(timeLoc, timeValue); + glUniform1f(scaleLoc, scale); + glUniform2f(mouseLoc, mousePos[0], mousePos[1]); - glUniform1f(timeLoc, timeValue); - glUniform1f(scaleLoc, scale); - glUniform2f(mouseLoc, mousePos[0], mousePos[1]); + frameCount++; - frameCount++; + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0); + glUseProgram(shaderProgram); - glUseProgram(shaderProgram); + glfwSwapBuffers(window); + } - glfwSwapBuffers(window); - } + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); + glDeleteBuffers(1, &EBO); + glDeleteProgram(shaderProgram); - glDeleteVertexArrays(1,&VAO); - glDeleteBuffers(1,&VBO); - glDeleteBuffers(1,&EBO); - glDeleteProgram(shaderProgram); - - glfwDestroyWindow(window); - glfwTerminate(); - return 0; + glfwDestroyWindow(window); + glfwTerminate(); + return 0; } -