diff --git a/CMakeLists.txt b/CMakeLists.txt index 79cf298..b988528 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,7 @@ include_directories("${CUDA_INCLUDE_DIRS}") # netcdf find_package(netCDF REQUIRED) -message(STATUS "Found netcdf in ${GLFW3_INCLUDE_DIR}") +message(STATUS "Found netcdf in ${NETCDF_INCLUDE_DIR}") execute_process( COMMAND nc-config --includedir diff --git a/src/consts.h b/src/consts.h index 7e6faad..ff5c4ef 100644 --- a/src/consts.h +++ b/src/consts.h @@ -76,4 +76,5 @@ extern __constant__ ColorStop d_stopsBluePurleRed[3]; // --------------------------- Functions for handling external constants --------------------------- void copyConstantsToDevice(); + #endif // CONSTS_H diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index dd15872..f0cfe3a 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -8,16 +8,6 @@ #include "input/Widget.h" -// TODO: Delete -void saveImage2(const char* filename, unsigned char* framebuffer, int width, int height) { // TODO: Figure out a better way to do this - std::ofstream imageFile(filename, std::ios::out | std::ios::binary); - imageFile << "P6\n" << width << " " << height << "\n255\n"; - for (int i = 0; i < width * height * 3; i++) { - imageFile << framebuffer[i]; - } - imageFile.close(); -} - Window::Window(unsigned int w, unsigned int h) { this->w = w; this->h = h; @@ -65,18 +55,10 @@ int Window::init(float* data) { // init imGUI this->widget = new Widget(this->window); - + // loop function for draw calls etc. while (!glfwWindowShouldClose(window)) { Window::tick(); } - // TODO: Remove this, this was just for ray-casting debug - // Window::tick(); - // Window::tick(); - // // Save the image - // unsigned char* pixels = new unsigned char[this->w * this->h * 3]; - // glReadPixels(0, 0, this->w, this->h, GL_RGB, GL_UNSIGNED_BYTE, pixels); - // saveImage2("output.ppm", pixels, this->w, this->h); - // delete[] pixels; Window::free(data); return 0; @@ -116,6 +98,10 @@ void Window::tick() { // input this->widget->tick(1000.0/diff); + if (this->widget->dateChanged) { + // TODO: Load new date file here + this->widget->dateChanged = false; + } // tick render glBindFramebuffer(GL_FRAMEBUFFER, 0); diff --git a/src/gui/input/Widget.cpp b/src/gui/input/Widget.cpp index 92001ef..a139464 100644 --- a/src/gui/input/Widget.cpp +++ b/src/gui/input/Widget.cpp @@ -3,9 +3,63 @@ #include "consts.h" #include #include +#include +// probably not the cleanest way to do this but it works +void parseDate(char* string, int dayOfYear) { + switch (dayOfYear) { + case 1 ... 31: + sprintf(string, "Jan %d", dayOfYear); + break; + case 32 ... 60: + sprintf(string, "Feb %d", dayOfYear-31); + break; + case 61 ... 91: + sprintf(string, "Mar %d", dayOfYear-60); + break; + case 92 ... 121: + sprintf(string, "Apr %d", dayOfYear-91); + break; + case 122 ... 152: + sprintf(string, "May %d", dayOfYear-121); + break; + case 153 ... 182: + sprintf(string, "Jun %d", dayOfYear-152); + break; + case 183 ... 213: + sprintf(string, "Jul %d", dayOfYear-182); + break; + case 214 ... 244: + sprintf(string, "Aug %d", dayOfYear-213); + break; + case 245 ... 274: + sprintf(string, "Sep %d", dayOfYear-244); + break; + case 275 ... 305: + sprintf(string, "Oct %d", dayOfYear-274); + break; + case 306 ... 335: + sprintf(string, "Nov %d", dayOfYear-305); + break; + case 336 ... 366: + sprintf(string, "Dec %d", dayOfYear-335); + break; + default: + sprintf(string, "∞"); + } +} -Widget::Widget(GLFWwindow* window) { +Widget::Widget(GLFWwindow* window) : + opacityK(0), + sigmoidOne(0.5f), + sigmoidTwo(-250.0f), + tfComboSelected(0), + dateChanged(false), + paused(true), + renderOnce(false), + bgColor(Color3::init(0.1f, 0.1f, 0.1f)), + date(0) +{ IMGUI_CHECKVERSION(); ImGui::CreateContext(); this->io = ImGui::GetIO(); @@ -13,23 +67,12 @@ Widget::Widget(GLFWwindow* window) { ImGui_ImplGlfw_InitForOpenGL(window, true); ImGui_ImplOpenGL3_Init(); - this->cameraPos = Point3::init(50.0f, -50.0f, -75.0f); // Camera for partially trimmed data set - // this->cameraPos = Point3::init(300.0f, 200.0f, -700.0f); // Camera for full data set - - Vec3 h_center = Vec3::init((float)VOLUME_WIDTH/2.0f, (float)VOLUME_HEIGHT/2.0f, (float)VOLUME_DEPTH/2.0f); - this->cameraDir = (h_center - this->cameraPos).normalize(); - - this->bgColor = Color3::init(0.1f, 0.1f, 0.1f); - this->lightPos = Point3::init(1.5, 2.0, -1.0); - this->fps = (char*)malloc(512*sizeof(char)); - this->paused = true; - this->renderOnce = false; + this->dateString = (char*)malloc(512*sizeof(char)); + sprintf(this->dateString, "January 1st"); - this->opacityK = 0; - this->sigmoidOne = 0.5f; - this->sigmoidTwo = -250.0f; - this->tfComboSelected = 0; + resetCamera(); + resetLight(); }; // REFACTOR: should probably not have all the logic in one function; something like a list of ImplementedWidgets with each a Render() function (a la interface) would be better. @@ -45,8 +88,6 @@ void Widget::tick(double fps) { ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - // input widgets - float min = -1, max = 1; ImGui::Begin("Transfer Function Controls"); ImGui::DragInt("k (log [1e-10, 1])", &this->opacityK, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp); @@ -71,13 +112,17 @@ void Widget::tick(double fps) { } ImGui::End(); + + float min = -1, max = 1; ImGui::Begin("Light Controls"); ImGui::DragScalar("X coordinate", ImGuiDataType_Double, &this->lightPos.x, 0.5f, &min, &max, "%.3f"); ImGui::DragScalar("Y coordinate", ImGuiDataType_Double, &this->lightPos.z, 0.5f, &min, &max, "%.3f"); ImGui::DragScalar("Z coordinate", ImGuiDataType_Double, &this->lightPos.y, 0.5f, &min, &max, "%.3f"); + if (ImGui::Button("Reset light")) resetLight(); ImGui::End(); - ImGui::Begin("Miscellaneous"); + + ImGui::Begin("Simulation Controls"); if (ImGui::Button(this->paused ? "Unpause" : "Pause")) this->paused = !this->paused; ImGui::SameLine(); if (ImGui::Button("Render once")) { @@ -86,15 +131,26 @@ void Widget::tick(double fps) { } sprintf(this->fps, "%.3f fps\n", fps); ImGui::Text(this->fps); + + // we have data from 2012-01-01 til 2012-09-11 == 255 days + ImGui::SetNextItemWidth(20.0f * ImGui::GetFontSize()); + if (ImGui::SliderInt("Day of year", &this->date, 1, 255, "%d", ImGuiSliderFlags_NoInput)) { + this->dateChanged = true; + parseDate(this->dateString, this->date); + } + ImGui::SameLine(); + ImGui::Text(this->dateString); ImGui::End(); + ImGui::Begin("Camera Controls"); ImGui::DragScalar("X position", ImGuiDataType_Double, &this->cameraPos.x, 0.5f, &min, &max, "%.3f"); ImGui::DragScalar("Y position", ImGuiDataType_Double, &this->cameraPos.z, 0.5f, &min, &max, "%.3f"); ImGui::DragScalar("Z position", ImGuiDataType_Double, &this->cameraPos.y, 0.5f, &min, &max, "%.3f"); - ImGui::DragScalar("X direction", ImGuiDataType_Double, &this->cameraDir.x, 0.005f, &min, &max, "%.3f"); + ImGui::DragScalar("X direction", ImGuiDataType_Double, &this->cameraDir.x, 0.005f, &min, &max, "%.3f"); // TODO: should wrap around once fully rotated ImGui::DragScalar("Y direction", ImGuiDataType_Double, &this->cameraDir.z, 0.005f, &min, &max, "%.3f"); ImGui::DragScalar("Z direction", ImGuiDataType_Double, &this->cameraDir.y, 0.005f, &min, &max, "%.3f"); + if (ImGui::Button("Reset camera")) resetCamera(); ImGui::End(); copyToDevice(); @@ -105,6 +161,19 @@ void Widget::render() { ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); } +void Widget::resetCamera() { + this->cameraPos = Point3::init(50.0f, -50.0f, -75.0f); // Camera for partially trimmed data set + // this->cameraPos = Point3::init(300.0f, 200.0f, -700.0f); // Camera for full data set + + Vec3 h_center = Vec3::init((float)VOLUME_WIDTH/2.0f, (float)VOLUME_HEIGHT/2.0f, (float)VOLUME_DEPTH/2.0f); + this->cameraDir = (h_center - this->cameraPos).normalize(); +} + + +void Widget::resetLight() { + this->lightPos = Point3::init(1.5, 2.0, -1.0); +} + void Widget::copyToDevice() { cudaMemcpyToSymbol(&d_cameraPos, &this->cameraPos, sizeof(Point3)); cudaMemcpyToSymbol(&d_cameraDir, &this->cameraDir, sizeof(Vec3)); @@ -125,4 +194,5 @@ Widget::~Widget() { ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); free(this->fps); + free(this->dateString); } diff --git a/src/gui/input/Widget.h b/src/gui/input/Widget.h index 15370c7..3df8e84 100644 --- a/src/gui/input/Widget.h +++ b/src/gui/input/Widget.h @@ -5,33 +5,47 @@ #include "../include/imgui/backends/imgui_impl_glfw.h" #include "../include/imgui/backends/imgui_impl_opengl3.h" #include +#include #include "linalg/linalg.h" class Widget { public: + bool paused; + bool dateChanged; + int date; + + void tick(double fps); + void render(); + + Widget(GLFWwindow* window); + ~Widget(); + +private: + // camera controls Point3 cameraDir; Vec3 cameraPos; - Point3 lightPos; - Color3 bgColor; // TODO: widget - bool paused; + // simulation cotnrols bool renderOnce; char* fps; + ImGuiIO io; + char *dateString; + // transfer function controls int tfComboSelected; int opacityK; float opacityKReal; float sigmoidOne; float sigmoidTwo; - ImGuiIO io; - - void tick(double fps); - void render(); + // miscellaneous + Point3 lightPos; + Color3 bgColor; // TODO: widget + void copyToDevice(); + void resetCamera(); + void resetLight(); - Widget(GLFWwindow* window); - ~Widget(); };