more code cleanup, now looks cleaner too
This commit is contained in:
parent
913a0429bd
commit
daf0814c08
2
Makefile
2
Makefile
@ -24,7 +24,7 @@ UNAME_S := $(shell uname -s)
|
|||||||
LINUX_GL_LIBS = -lGL
|
LINUX_GL_LIBS = -lGL
|
||||||
|
|
||||||
CXXFLAGS = -std=c++20 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
CXXFLAGS = -std=c++20 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
CXXFLAGS += -g -DIMGUI_DEFINE_MATH_OPERATORS -Ofast
|
CXXFLAGS += -DIMGUI_DEFINE_MATH_OPERATORS -Ofast
|
||||||
LIBS =
|
LIBS =
|
||||||
|
|
||||||
##---------------------------------------------------------------------
|
##---------------------------------------------------------------------
|
||||||
|
13
imgui.ini
13
imgui.ini
@ -1,6 +1,5 @@
|
|||||||
[Window][Debug##Default]
|
[Window][Debug##Default]
|
||||||
ViewportPos=1277,2517
|
Pos=341,6
|
||||||
ViewportId=0x9F5F46A1
|
|
||||||
Size=400,400
|
Size=400,400
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
@ -9,16 +8,12 @@ Size=1101,598
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Editor]
|
[Window][Editor]
|
||||||
Pos=8,27
|
Pos=33,52
|
||||||
Size=1118,634
|
Size=1118,634
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x12F98E09,0
|
|
||||||
|
|
||||||
[Window][Main]
|
[Window][Main]
|
||||||
Pos=0,19
|
Pos=0,0
|
||||||
Size=1134,650
|
Size=1720,1148
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Docking][Data]
|
|
||||||
DockSpace ID=0x12F98E09 Window=0x1F1A625A Pos=2505,2927 Size=1118,634 CentralNode=1 Selected=0x9F27EDF6
|
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ void SetNextPanelFlags(InspectorFlags setFlags, InspectorFlags clearFlags)
|
|||||||
bool BeginInspectorPanel(const char *title, ImTextureID texture, ImVec2 textureSize, InspectorFlags flags,
|
bool BeginInspectorPanel(const char *title, ImTextureID texture, ImVec2 textureSize, InspectorFlags flags,
|
||||||
SizeIncludingBorder sizeIncludingBorder)
|
SizeIncludingBorder sizeIncludingBorder)
|
||||||
{
|
{
|
||||||
const int borderWidth = 1;
|
const int borderWidth = 0;
|
||||||
// Unpack size param. It's in the SizeIncludingBorder structure just to make sure users know what they're requesting
|
// Unpack size param. It's in the SizeIncludingBorder structure just to make sure users know what they're requesting
|
||||||
ImVec2 size = sizeIncludingBorder.Size;
|
ImVec2 size = sizeIncludingBorder.Size;
|
||||||
|
|
||||||
@ -389,7 +389,7 @@ bool BeginInspectorPanel(const char *name, ImTextureID texture, ImVec2 textureSi
|
|||||||
void EndInspectorPanel()
|
void EndInspectorPanel()
|
||||||
{
|
{
|
||||||
const ImU32 innerBorderColour = 0xFFFFFFFF;
|
const ImU32 innerBorderColour = 0xFFFFFFFF;
|
||||||
const ImU32 outerBorderColour = 0xFF888888;
|
const ImU32 outerBorderColour = 0x00000000;
|
||||||
Inspector *inspector = GContext->CurrentInspector;
|
Inspector *inspector = GContext->CurrentInspector;
|
||||||
|
|
||||||
// Draw out border around whole inspector panel
|
// Draw out border around whole inspector panel
|
||||||
|
@ -1,534 +0,0 @@
|
|||||||
|
|
||||||
#include "../ImNodeFlow.h"
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iterator>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
|
||||||
#include <SDL2/SDL_opengles.h>
|
|
||||||
#else
|
|
||||||
#include <SDL2/SDL_opengl.h>
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <SDL.h>
|
|
||||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
|
||||||
#include <SDL_opengles2.h>
|
|
||||||
#else
|
|
||||||
#include <SDL_opengl.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../image_model.h"
|
|
||||||
#include "../imfilebrowser.h"
|
|
||||||
#include "../stb_image.h"
|
|
||||||
#include "../uuid.h"
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include "../emscripten_browser_file.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct Texture {
|
|
||||||
ImTextureID texture;
|
|
||||||
ImVec2 size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LoadCallback {
|
|
||||||
std::string filename;
|
|
||||||
std::string mime_type;
|
|
||||||
std::string_view buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Exposure : public ImFlow::BaseNode {
|
|
||||||
public:
|
|
||||||
ImageBundle returnBundle;
|
|
||||||
Exposure() {
|
|
||||||
setTitle("Exposure");
|
|
||||||
setStyle(ImFlow::NodeStyle::green());
|
|
||||||
addIN<ImageBundle>("Image", ImageBundle());
|
|
||||||
addOUT<ImageBundle>("Image Out")->behaviour([this]() {
|
|
||||||
return returnBundle;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~Exposure() { stbi_image_free(returnBundle.image); }
|
|
||||||
|
|
||||||
void draw() override {
|
|
||||||
ImGui::SetNextItemWidth(100);
|
|
||||||
ImGui::SliderInt("", &brightnessVal, -255, 255);
|
|
||||||
ImageBundle val = getInVal<ImageBundle>("Image");
|
|
||||||
|
|
||||||
// If the input is valid, and out buffers are not
|
|
||||||
if (val.loaded && !returnBundle.loaded) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.loaded = true;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input is invalid, and are buffers are valid
|
|
||||||
if (!val.loaded && returnBundle.loaded) {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
returnBundle.loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input has changed
|
|
||||||
if (val.fname != fname) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
int old_img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
if (img_size == old_img_size) {
|
|
||||||
memcpy(returnBundle.image, val.image, img_size);
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
} else {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnBundle.loaded) {
|
|
||||||
if (brightnessVal != prev_brightness) {
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
prev_brightness = brightnessVal;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static int formula(uint8_t color, int val) {
|
|
||||||
float vf = static_cast<float>(val) / 255.0;
|
|
||||||
vf = vf + 1.0;
|
|
||||||
float cf = static_cast<float>(color) / 255.0;
|
|
||||||
float ret_val = (cf * vf) * 255.0f;
|
|
||||||
return static_cast<int>(ret_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute(uint8_t *input, uint8_t *output, int size, int channels) {
|
|
||||||
for (int i = 0; i < size; i += channels) {
|
|
||||||
uint8_t r = std::clamp(formula(input[i], brightnessVal), 0, 255);
|
|
||||||
uint8_t g = std::clamp(formula(input[i + 1], brightnessVal), 0, 255);
|
|
||||||
uint8_t b = std::clamp(formula(input[i + 2], brightnessVal), 0, 255);
|
|
||||||
output[i] = r;
|
|
||||||
output[i + 1] = g;
|
|
||||||
output[i + 2] = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int brightnessVal = 0;
|
|
||||||
int prev_brightness = 0;
|
|
||||||
std::string fname;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Contrast : public ImFlow::BaseNode {
|
|
||||||
public:
|
|
||||||
ImageBundle returnBundle;
|
|
||||||
Contrast() {
|
|
||||||
setTitle("Contrast");
|
|
||||||
setStyle(ImFlow::NodeStyle::green());
|
|
||||||
addIN<ImageBundle>("Image", ImageBundle());
|
|
||||||
addOUT<ImageBundle>("Image Out")->behaviour([this]() {
|
|
||||||
return returnBundle;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~Contrast() { stbi_image_free(returnBundle.image); }
|
|
||||||
|
|
||||||
void draw() override {
|
|
||||||
ImGui::SetNextItemWidth(100);
|
|
||||||
ImGui::SliderInt("", &brightnessVal, -255, 255);
|
|
||||||
ImageBundle val = getInVal<ImageBundle>("Image");
|
|
||||||
|
|
||||||
// If the input is valid, and out buffers are not
|
|
||||||
if (val.loaded && !returnBundle.loaded) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.loaded = true;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input is invalid, and are buffers are valid
|
|
||||||
if (!val.loaded && returnBundle.loaded) {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
returnBundle.loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input has changed
|
|
||||||
if (val.fname != fname) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
int old_img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
if (img_size == old_img_size) {
|
|
||||||
memcpy(returnBundle.image, val.image, img_size);
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
} else {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnBundle.loaded) {
|
|
||||||
if (brightnessVal != prev_brightness) {
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
prev_brightness = brightnessVal;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static int formula(uint8_t color, int val) {
|
|
||||||
float vf = static_cast<float>(val) / 255.0;
|
|
||||||
vf = vf + 1.0;
|
|
||||||
float cf = static_cast<float>(color) / 255.0;
|
|
||||||
float ret_val = (((cf - 0.5f) * vf) + 0.5f) * 255.0f;
|
|
||||||
return static_cast<int>(ret_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compute(uint8_t *input, uint8_t *output, int size, int channels) {
|
|
||||||
int nBval = brightnessVal + 256;
|
|
||||||
for (int i = 0; i < size; i += channels) {
|
|
||||||
uint8_t r = std::clamp(formula(input[i], brightnessVal), 0, 255);
|
|
||||||
uint8_t g = std::clamp(formula(input[i + 1], brightnessVal), 0, 255);
|
|
||||||
uint8_t b = std::clamp(formula(input[i + 2], brightnessVal), 0, 255);
|
|
||||||
output[i] = r;
|
|
||||||
output[i + 1] = g;
|
|
||||||
output[i + 2] = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int brightnessVal = 0;
|
|
||||||
int prev_brightness = 0;
|
|
||||||
std::string fname;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SimpleBrightness : public ImFlow::BaseNode {
|
|
||||||
public:
|
|
||||||
ImageBundle returnBundle;
|
|
||||||
SimpleBrightness() {
|
|
||||||
setTitle("Simple Brightness");
|
|
||||||
setStyle(ImFlow::NodeStyle::green());
|
|
||||||
addIN<ImageBundle>("Image", ImageBundle());
|
|
||||||
addOUT<ImageBundle>("Image Out")->behaviour([this]() {
|
|
||||||
return returnBundle;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~SimpleBrightness() { stbi_image_free(returnBundle.image); }
|
|
||||||
|
|
||||||
void draw() override {
|
|
||||||
ImGui::SetNextItemWidth(100);
|
|
||||||
ImGui::SliderInt("", &brightnessVal, -255, 255);
|
|
||||||
ImageBundle val = getInVal<ImageBundle>("Image");
|
|
||||||
|
|
||||||
// If the input is valid, and out buffers are not
|
|
||||||
if (val.loaded && !returnBundle.loaded) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.loaded = true;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input is invalid, and are buffers are valid
|
|
||||||
if (!val.loaded && returnBundle.loaded) {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
returnBundle.loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the input has changed
|
|
||||||
if (val.fname != fname) {
|
|
||||||
int img_size = val.width * val.height * val.channels;
|
|
||||||
int old_img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
if (img_size == old_img_size) {
|
|
||||||
memcpy(returnBundle.image, val.image, img_size);
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
} else {
|
|
||||||
stbi_image_free(returnBundle.image);
|
|
||||||
uint8_t *duplicated_img = (uint8_t *)malloc(img_size);
|
|
||||||
memcpy(duplicated_img, val.image, img_size);
|
|
||||||
returnBundle.image = duplicated_img;
|
|
||||||
returnBundle.height = val.height;
|
|
||||||
returnBundle.width = val.width;
|
|
||||||
returnBundle.channels = val.channels;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
fname = val.fname;
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnBundle.loaded) {
|
|
||||||
if (brightnessVal != prev_brightness) {
|
|
||||||
int img_size =
|
|
||||||
returnBundle.width * returnBundle.height * returnBundle.channels;
|
|
||||||
compute(val.image, returnBundle.image, img_size, returnBundle.channels);
|
|
||||||
prev_brightness = brightnessVal;
|
|
||||||
returnBundle.fname = uuid::generate_uuid_v4();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void compute(uint8_t *input, uint8_t *output, int size, int channels) {
|
|
||||||
for (int i = 0; i < size; i += channels) {
|
|
||||||
uint8_t r = std::clamp(input[i] + brightnessVal, 0, 255);
|
|
||||||
uint8_t g = std::clamp(input[i + 1] + brightnessVal, 0, 255);
|
|
||||||
uint8_t b = std::clamp(input[i + 2] + brightnessVal, 0, 255);
|
|
||||||
output[i] = r;
|
|
||||||
output[i + 1] = g;
|
|
||||||
output[i + 2] = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int brightnessVal = 0;
|
|
||||||
int prev_brightness = 0;
|
|
||||||
std::string fname;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PreviewImage : public ImFlow::BaseNode {
|
|
||||||
public:
|
|
||||||
PreviewImage() {
|
|
||||||
setTitle("Output");
|
|
||||||
setStyle(ImFlow::NodeStyle::cyan());
|
|
||||||
addIN<ImageBundle>("Image", ImageBundle());
|
|
||||||
}
|
|
||||||
|
|
||||||
~PreviewImage() {
|
|
||||||
if (loaded) {
|
|
||||||
glDeleteTextures(1, &txHandle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() override {
|
|
||||||
ImageBundle val = getInVal<ImageBundle>("Image");
|
|
||||||
if (val.loaded && !loaded) {
|
|
||||||
GLuint textureHandle;
|
|
||||||
glGenTextures(1, &textureHandle);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
|
||||||
GL_CLAMP_TO_EDGE); // This is required on WebGL for non
|
|
||||||
// power-of-two textures
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
|
||||||
GL_CLAMP_TO_EDGE); // Same
|
|
||||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
#endif
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, val.width, val.height, 0, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, val.image);
|
|
||||||
|
|
||||||
txHandle = textureHandle;
|
|
||||||
id = val.fname;
|
|
||||||
loaded = true;
|
|
||||||
prev_h = val.height;
|
|
||||||
prev_w = val.width;
|
|
||||||
}
|
|
||||||
if (!val.loaded && loaded) {
|
|
||||||
glDeleteTextures(1, &txHandle);
|
|
||||||
loaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((val.fname != id) && loaded) {
|
|
||||||
if (prev_w != val.width || prev_h != val.height) {
|
|
||||||
glDeleteTextures(1, &txHandle);
|
|
||||||
GLuint textureHandle;
|
|
||||||
glGenTextures(1, &textureHandle);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
|
||||||
GL_CLAMP_TO_EDGE); // This is required on WebGL for non
|
|
||||||
// power-of-two textures
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
|
||||||
GL_CLAMP_TO_EDGE); // Same
|
|
||||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
#endif
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, val.width, val.height, 0,
|
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, val.image);
|
|
||||||
|
|
||||||
txHandle = textureHandle;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, txHandle);
|
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, val.width, val.height, GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE, val.image);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
prev_h = val.height;
|
|
||||||
prev_w = val.width;
|
|
||||||
id = val.fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loaded) {
|
|
||||||
if (val.height < val.width) {
|
|
||||||
ImGui::Image((void *)(intptr_t)txHandle,
|
|
||||||
ImVec2(256, val.calcResizedWidth(256)));
|
|
||||||
} else {
|
|
||||||
ImGui::Image((void *)(intptr_t)txHandle,
|
|
||||||
ImVec2(val.calcResizedHeight(256), 256));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int prev_h = 0;
|
|
||||||
int prev_w = 0;
|
|
||||||
bool loaded = false;
|
|
||||||
GLuint txHandle;
|
|
||||||
std::string id;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LoadImage : public ImFlow::BaseNode {
|
|
||||||
public:
|
|
||||||
ImageBundle bundle;
|
|
||||||
|
|
||||||
LoadImage() {
|
|
||||||
setTitle("Load Image");
|
|
||||||
setStyle(ImFlow::NodeStyle::brown());
|
|
||||||
addOUT<ImageBundle>("Image")->behaviour([this]() { return bundle; });
|
|
||||||
}
|
|
||||||
|
|
||||||
~LoadImage() {
|
|
||||||
if (bundle.loaded) {
|
|
||||||
stbi_image_free(bundle.image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() override {
|
|
||||||
LoadCallback lc = LoadCallback();
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
if (ImGui::Button("Select File")) {
|
|
||||||
emscripten_browser_file::upload(".png,.jpg,.jpeg", handle_upload_file,
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (bundle.fname == "") {
|
|
||||||
handle_upload_file_local(
|
|
||||||
"/Users/tanishqdubey/Downloads/Odd-eyed_cat_by_ihasb33r.jpg", this);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (bundle.fname != "") {
|
|
||||||
bundle.loaded = true;
|
|
||||||
ImGui::Text("File Loaded");
|
|
||||||
} else {
|
|
||||||
ImGui::Text("No image loaded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool showPreview = false;
|
|
||||||
|
|
||||||
static void handle_upload_file_local(const char *filename, void *callback) {
|
|
||||||
auto lc{reinterpret_cast<LoadImage *>(callback)};
|
|
||||||
const int channelCount = 4;
|
|
||||||
int imageFileChannelCount;
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
uint8_t *image = (uint8_t *)stbi_load(filename, &width, &height,
|
|
||||||
&imageFileChannelCount, channelCount);
|
|
||||||
|
|
||||||
if (image == NULL) {
|
|
||||||
fprintf(stderr, "%s\nFailed to open %s\n", stbi_failure_reason(),
|
|
||||||
lc->bundle.fname.c_str());
|
|
||||||
lc->bundle.fname = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
lc->bundle.fname = uuid::generate_uuid_v4();
|
|
||||||
lc->bundle.width = width;
|
|
||||||
lc->bundle.height = height;
|
|
||||||
lc->bundle.channels = channelCount;
|
|
||||||
lc->bundle.image = image;
|
|
||||||
lc->bundle.loaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_upload_file(std::string const &filename,
|
|
||||||
std::string const &mime_type,
|
|
||||||
std::string_view buffer, void *callback) {
|
|
||||||
auto lc{reinterpret_cast<LoadImage *>(callback)};
|
|
||||||
const int channelCount = 4;
|
|
||||||
int imageFileChannelCount;
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
auto d = buffer.data();
|
|
||||||
stbi_uc *image = (stbi_uc *)stbi_load_from_memory(
|
|
||||||
(const stbi_uc *)buffer.data(), buffer.size(), &width, &height,
|
|
||||||
&imageFileChannelCount, channelCount);
|
|
||||||
|
|
||||||
if (image == NULL) {
|
|
||||||
fprintf(stderr, "%s\nFailed to open %s - %s\n", stbi_failure_reason(),
|
|
||||||
filename.c_str(), mime_type.c_str());
|
|
||||||
lc->bundle.fname = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
lc->bundle.fname = uuid::generate_uuid_v4();
|
|
||||||
lc->bundle.width = width;
|
|
||||||
lc->bundle.height = height;
|
|
||||||
lc->bundle.channels = channelCount;
|
|
||||||
lc->bundle.image = image;
|
|
||||||
lc->bundle.loaded = true;
|
|
||||||
}
|
|
||||||
};
|
|
88
main.cpp
88
main.cpp
@ -15,6 +15,7 @@
|
|||||||
#include "lib/backends/imgui_impl_sdl2.h"
|
#include "lib/backends/imgui_impl_sdl2.h"
|
||||||
#include "lib/imgui.h"
|
#include "lib/imgui.h"
|
||||||
#include "lib/imgui_internal.h"
|
#include "lib/imgui_internal.h"
|
||||||
|
#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
@ -144,29 +145,14 @@ int main(int, char **) {
|
|||||||
(void)io;
|
(void)io;
|
||||||
io.ConfigFlags |=
|
io.ConfigFlags |=
|
||||||
ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport /
|
|
||||||
// Platform Windows
|
|
||||||
// io.ConfigViewportsNoAutoMerge = true;
|
|
||||||
// io.ConfigViewportsNoTaskBarIcon = true;
|
|
||||||
//
|
|
||||||
ImGuiTexInspect::ImplOpenGL3_Init(); // Or DirectX 11 equivalent (check your chosen backend header file)
|
ImGuiTexInspect::ImplOpenGL3_Init(); // Or DirectX 11 equivalent (check your chosen backend header file)
|
||||||
ImGuiTexInspect::Init();
|
ImGuiTexInspect::Init();
|
||||||
ImGuiTexInspect::CreateContext();
|
ImGuiTexInspect::CreateContext();
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
// ImGui::StyleColorsLight();
|
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform
|
|
||||||
// windows can look identical to regular ones.
|
|
||||||
ImGuiStyle &style = ImGui::GetStyle();
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
|
||||||
style.WindowRounding = 0.0f;
|
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
|
||||||
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
|
||||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||||
|
|
||||||
@ -179,14 +165,6 @@ int main(int, char **) {
|
|||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
// Poll and handle events (inputs, window resize, etc.)
|
// Poll and handle events (inputs, window resize, etc.)
|
||||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to
|
|
||||||
// tell if dear imgui wants to use your inputs.
|
|
||||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to
|
|
||||||
// your main application, or clear/overwrite your copy of the mouse data.
|
|
||||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input
|
|
||||||
// data to your main application, or clear/overwrite your copy of the
|
|
||||||
// keyboard data. Generally you may always pass all inputs to dear imgui,
|
|
||||||
// and hide them from your application based on those two flags.
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||||
@ -203,6 +181,11 @@ int main(int, char **) {
|
|||||||
ImGui_ImplSDL2_NewFrame();
|
ImGui_ImplSDL2_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
if (init) {
|
||||||
|
init = false;
|
||||||
|
t = LoadTexture("/home/dubey/Pictures/DSC03199.JPG");
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef IMGUI_HAS_VIEWPORT
|
#ifdef IMGUI_HAS_VIEWPORT
|
||||||
ImGuiViewport *viewport = ImGui::GetMainViewport();
|
ImGuiViewport *viewport = ImGui::GetMainViewport();
|
||||||
@ -214,42 +197,27 @@ int main(int, char **) {
|
|||||||
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
|
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::SetNextWindowPos(viewport->Pos);
|
||||||
|
ImGui::SetNextWindowSize(viewport->Size);
|
||||||
ImGui::Begin("Main", NULL,
|
ImGui::Begin("Main", NULL,
|
||||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
||||||
ImGuiID dockspace_id = ImGui::GetID("MyDockspace");
|
auto wSize = ImGui::GetContentRegionAvail();
|
||||||
ImGuiDockNodeFlags dockspace_flags =
|
if (t.texture != 0) {
|
||||||
ImGuiDockNodeFlags_PassthruCentralNode;
|
ImGuiTexInspect::BeginInspectorPanel(
|
||||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f));
|
"Inspector",
|
||||||
|
t.texture,
|
||||||
if (init) {
|
t.size,
|
||||||
init = false;
|
ImGuiTexInspect::InspectorFlags_FillVertical | ImGuiTexInspect::InspectorFlags_FillHorizontal,
|
||||||
ImGui::DockBuilderRemoveNode(dockspace_id);
|
ImGuiTexInspect::SizeExcludingBorder(wSize)
|
||||||
ImGui::DockBuilderAddNode(
|
);
|
||||||
dockspace_id, dockspace_flags | ImGuiDockNodeFlags_DockSpace);
|
ImGuiTexInspect::EndInspectorPanel();
|
||||||
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
|
|
||||||
ImGui::DockBuilderDockWindow("Editor", dockspace_id);
|
|
||||||
ImGui::DockBuilderFinish(dockspace_id);
|
|
||||||
t = LoadTexture("/home/dubey/Pictures/DSC03199.JPG");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar()) {
|
|
||||||
if (ImGui::BeginMenu("File")) {
|
|
||||||
if (ImGui::MenuItem("Open")) {
|
|
||||||
}
|
|
||||||
if (ImGui::MenuItem("Exit")) {
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Begin("Editor", NULL,
|
|
||||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
|
||||||
// -- MAIN WINDOW HERE
|
|
||||||
ImGui::End();
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
@ -259,20 +227,6 @@ int main(int, char **) {
|
|||||||
clear_color.z * clear_color.w, clear_color.w);
|
clear_color.z * clear_color.w, clear_color.w);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
// (Platform functions may change the current OpenGL context, so we
|
|
||||||
// save/restore it to make it easier to paste this code elsewhere.
|
|
||||||
// For this specific demo app we could also call SDL_GL_MakeCurrent(window,
|
|
||||||
// gl_context) directly)
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
|
|
||||||
SDL_Window *backup_current_window = SDL_GL_GetCurrentWindow();
|
|
||||||
SDL_GLContext backup_current_context = SDL_GL_GetCurrentContext();
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user