1+ #include " ImageView.h"
2+ #include " ImageCh.h"
3+ #include " PPMReader.h"
4+ #include < imgui.h>
5+
6+ ImageView::ImageView (const PPMImageData& image, u8 pixelSize) : m_image(image), m_pixelSize(pixelSize) {}
7+
8+ int ImageView::init () {
9+
10+ u64 imageWidth = m_image[0 ].width ();
11+ u64 imageHeight = m_image[0 ].height ();
12+
13+ u64 scaled_width = imageWidth * m_pixelSize;
14+ u64 scaled_height = imageHeight * m_pixelSize;
15+
16+ if (Window::init (scaled_width, scaled_height, " ImageView" )) {
17+ ERROR (" Failed to init window inside image view\n " );
18+ return 1 ;
19+ }
20+ if (Overlay::init (getGLFWWindow ())) {
21+ ERROR (" Failed to init overlay inside image view\n " );
22+ return 1 ;
23+ }
24+ set_font (" ../../Fonts/CascadiaMono/CaskaydiaMonoNerdFontPropo-Regular.ttf" , 14 );
25+
26+ m_data.resize (scaled_width * scaled_height * 4 );
27+ for (int y = 0 ; y < imageHeight; ++y) {
28+ for (int x = 0 ; x < imageWidth; ++x) {
29+ u8 r = m_image[0 ](y, x);
30+ u8 g = m_image[1 ](y, x);
31+ u8 b = m_image[2 ](y, x);
32+ u8 a = 255 ;
33+
34+ for (int dy = 0 ; dy < m_pixelSize; ++dy) {
35+ for (int dx = 0 ; dx < m_pixelSize; ++dx) {
36+ int dest_x = x * m_pixelSize + dx;
37+ int dest_y = y * m_pixelSize + dy;
38+ int dest_idx = (dest_y * scaled_width + dest_x) * 4 ;
39+ m_data[dest_idx + 0 ] = r;
40+ m_data[dest_idx + 1 ] = g;
41+ m_data[dest_idx + 2 ] = b;
42+ m_data[dest_idx + 3 ] = a;
43+ }
44+ }
45+ }
46+ }
47+
48+ print (" " , m_image[0 ]);
49+ print (" " , m_image[1 ]);
50+ print (" " , m_image[2 ]);
51+
52+ glGenTextures (1 , &m_texture);
53+ glBindTexture (GL_TEXTURE_2D, m_texture);
54+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
55+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
56+ glTexImage2D (GL_TEXTURE_2D, 0 , GL_RGBA, scaled_width, scaled_height,
57+ 0 , GL_RGBA, GL_UNSIGNED_BYTE, m_data.data ());
58+ float vertices[] = {
59+ // positions // tex coords
60+ -1 .f , -1 .f , 0 .f , 1 .f ,
61+ 1 .f , -1 .f , 1 .f , 1 .f ,
62+ 1 .f , 1 .f , 1 .f , 0 .f ,
63+ -1 .f , 1 .f , 0 .f , 0 .f
64+ };
65+ unsigned int indices[] = { 0 , 1 , 2 , 2 , 3 , 0 };
66+
67+ glGenVertexArrays (1 , &m_vao);
68+ glGenBuffers (1 , &m_vbo);
69+ GLuint ebo;
70+ glGenBuffers (1 , &ebo);
71+
72+ glBindVertexArray (m_vao);
73+
74+ glBindBuffer (GL_ARRAY_BUFFER, m_vbo);
75+ glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW);
76+
77+ glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, ebo);
78+ glBufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW);
79+
80+ // positions
81+ glVertexAttribPointer (0 , 2 , GL_FLOAT, GL_FALSE, 4 * sizeof (float ), (void *)0 );
82+ glEnableVertexAttribArray (0 );
83+ // texcoords
84+ glVertexAttribPointer (1 , 2 , GL_FLOAT, GL_FALSE, 4 * sizeof (float ), (void *)(2 * sizeof (float )));
85+ glEnableVertexAttribArray (1 );
86+
87+ glBindVertexArray (0 );
88+
89+ // Shaders
90+ const char * vertSrc = R"(
91+ #version 330 core
92+ layout(location = 0) in vec2 aPos;
93+ layout(location = 1) in vec2 aTex;
94+ out vec2 TexCoord;
95+ void main() {
96+ gl_Position = vec4(aPos, 0.0, 1.0);
97+ TexCoord = aTex;
98+ })" ;
99+
100+ const char * fragSrc = R"(
101+ #version 330 core
102+ out vec4 FragColor;
103+ in vec2 TexCoord;
104+ uniform sampler2D tex;
105+ void main() {
106+ FragColor = texture(tex, TexCoord);
107+ })" ;
108+
109+ GLuint vert = compileShader (GL_VERTEX_SHADER, vertSrc);
110+ GLuint frag = compileShader (GL_FRAGMENT_SHADER, fragSrc);
111+ m_shaderProgram = glCreateProgram ();
112+ glAttachShader (m_shaderProgram, vert);
113+ glAttachShader (m_shaderProgram, frag);
114+ glLinkProgram (m_shaderProgram);
115+ glDeleteShader (vert);
116+ glDeleteShader (frag);
117+ return 0 ;
118+ }
119+
120+ void ImageView::overlay () {
121+
122+ // Если в одном окне нужно будет переключаться между режимами
123+ // if (ImGui::BeginTabBar("Tabs")) {
124+
125+ // if (ImGui::BeginTabItem("Input")) {
126+ // ImGui::Text("This is the Home tab.");
127+ // ImGui::EndTabItem();
128+ // }
129+
130+ // if (ImGui::BeginTabItem("DCT")) {
131+ // ImGui::Text("This is the Settings tab.");
132+ // ImGui::EndTabItem();
133+ // }
134+
135+ // ImGui::EndTabBar();
136+ // }
137+
138+ ImVec2 mousePos = ImGui::GetMousePos ();
139+ ImVec2 windowPos = ImGui::GetWindowPos ();
140+ ImVec2 windowSize = ImGui::GetWindowSize ();
141+
142+ bool isMouseInWindow = mousePos.x >= windowPos.x &&
143+ mousePos.x <= windowPos.x + windowSize.x &&
144+ mousePos.y >= windowPos.y &&
145+ mousePos.y <= windowPos.y + windowSize.y ;
146+
147+ if (!isMouseInWindow) {
148+ return ;
149+ }
150+
151+ ImVec2 mouse_local = ImVec2 (mousePos.x - windowPos.x , mousePos.y - windowPos.y );
152+
153+ u64 pixel_i_cord = std::trunc ((static_cast <float >(mouse_local.x ) / static_cast <float >(m_pixelSize)));
154+ u64 pixel_j_cord = std::trunc ((static_cast <float >(mouse_local.y ) / static_cast <float >(m_pixelSize)));
155+
156+ u64 pixel_i_center = pixel_i_cord * m_pixelSize;
157+ u64 pixel_j_center = pixel_j_cord * m_pixelSize;
158+
159+ ImVec2 p_min (pixel_i_center, pixel_j_center);
160+ ImVec2 p_max (pixel_i_center + m_pixelSize, pixel_j_center + m_pixelSize);
161+
162+ ImGui::SetNextWindowPos (ImVec2 (0 , 0 ));
163+ ImGui::SetNextWindowSize (ImGui::GetIO ().DisplaySize );
164+ ImGui::SetNextWindowBgAlpha (0 .2f );
165+
166+
167+ ImGui::Begin (" Overlay" , nullptr ,
168+ ImGuiWindowFlags_NoMove |
169+ ImGuiWindowFlags_NoTitleBar |
170+ ImGuiWindowFlags_NoResize |
171+ ImGuiWindowFlags_AlwaysAutoResize |
172+ ImGuiWindowFlags_NoSavedSettings |
173+ ImGuiWindowFlags_NoFocusOnAppearing |
174+ ImGuiWindowFlags_NoNav);
175+ ImDrawList* draw_list = ImGui::GetWindowDrawList ();
176+ // ImGui::setw
177+
178+ ImGui::Text (" X: %lu" , pixel_i_cord);
179+ ImGui::Text (" Y: %lu" , pixel_j_cord);
180+ ImGui::Text (" R: %d" , m_image[0 ](pixel_j_cord, pixel_i_cord));
181+ ImGui::Text (" G: %d" , m_image[1 ](pixel_j_cord, pixel_i_cord));
182+ ImGui::Text (" B: %d" , m_image[2 ](pixel_j_cord, pixel_i_cord));
183+
184+ draw_list->AddRect (p_min, p_max, IM_COL32 (255 , 0 , 0 , 255 ), 0 .0f , 0 , 3 .0f );
185+
186+ // TODO: draw pixel value text on pixel?
187+ // draw_list->AddText(ImVec2(pixel_i_center, pixel_j_center), ImColor(255, 255, 255, 255), "R");
188+
189+ ImGui::End ();
190+ }
191+
192+ int ImageView::render () {
193+
194+ glfwMakeContextCurrent (getGLFWWindow ());
195+
196+ Window::render ();
197+
198+ glClear (GL_COLOR_BUFFER_BIT);
199+
200+ glUseProgram (m_shaderProgram);
201+ glBindVertexArray (m_vao);
202+ glActiveTexture (GL_TEXTURE0);
203+ glBindTexture (GL_TEXTURE_2D, m_texture);
204+ glUniform1i (glGetUniformLocation (m_shaderProgram, " tex" ), 0 );
205+
206+ glDrawElements (GL_TRIANGLES, 6 , GL_UNSIGNED_INT, 0 );
207+
208+ glBindVertexArray (0 );
209+
210+ Overlay::render ();
211+
212+ glfwSwapBuffers (getGLFWWindow ());
213+
214+ return 0 ;
215+ }
0 commit comments