#include "stdafx.h" #include #include #include #include #include #include using namespace std; #define Width 600 #define Height 640 typedef struct Point { GLint x, y; } Point; typedef struct Edge { vector p; } Edge; typedef struct RGB_type { float red, green, blue; } RGB_type; RGB_type pixels[Width*Height]; vector points; vector edges; GLFWwindow* window; bool running = true; int mouseX, mouseY; int oldMouseX = -1, oldMouseY = -1; int FirstMouseX = -1, FirstMouseY = -1; int oldY = 0, firstY1; bool last = false; int GetIndex(int x, int y) { return (x + (Height - y)*Width); } void SetPixel(int x, int y, int c) { int ind = GetIndex(x, y); pixels[ind].red = c; pixels[ind].blue = c; pixels[ind].green = c; } void Fill() { for (int i = 0; i < Height - 1; i++) { bool flag = false; for (int j = 1; j < Width - 1; j++) { if (pixels[GetIndex(j, i)].blue == 1) flag = !flag; flag ? SetPixel(j, i, 1) : SetPixel(j, i, 0); } } } void DrawLine(int x0, int y0, int x1, int y1) { if (oldY == 0) firstY1 = y1; int x = x0; int y = y0; int lastY; if ((y0 - oldY) * (y1 - y0) < 0) SetPixel(x + 1, y, 1); int dx = abs(x1 - x0); int dy = abs(y1 - y0); int signX = (x0 < x1) ? 1 : -1; int signY = (y0 < y1) ? 1 : -1; int e2 = 2 * dx - dy; SetPixel(x, y, 1); for (int i = 0; i < dy - 1 + last; i++) { lastY = y; while (e2 >= 0) { x += signX; e2 -= 2 * dy; } y += signY; e2 += 2 * dx; if (pixels[GetIndex(x, y)].blue == 1) SetPixel(x + 1, y, 1); SetPixel(x, y, 1); } oldY = y0; } void PostFilter() { RGB_type *pNew = nullptr; pNew = new RGB_type[Width*Height]; double errR, errG, errB; for (int y = 1; y < Height - 1; y++) for (int x = 1; x < Width - 1; x++) { errR = errG = errB = 0; for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { errR += pixels[GetIndex(j + x, i + y)].red; errG += pixels[GetIndex(j + x, i + y)].green; errB += pixels[GetIndex(j + x, i + y)].blue; } } errR /= 9; errB /= 9; errG /= 9; pNew[GetIndex(x, y)].red = errR; pNew[GetIndex(x, y)].green = errG; pNew[GetIndex(x, y)].blue = errB; } for (int i = 0; i < Width*Height - 1; i++) { pixels[i].blue = pNew[i].blue; pixels[i].red = pNew[i].red; pixels[i].green = pNew[i].green; } delete[]pNew; } void Clear() { for (int i = 0; i < Width*Height; i++) pixels[i] = { 0, 0, 0 }; oldMouseX = -1; oldMouseY = -1; FirstMouseX = -1; FirstMouseY = -1; last = 0; } static void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) running = false; if (key == GLFW_KEY_D && action == GLFW_PRESS) Fill(); if (key == GLFW_KEY_S && action == GLFW_PRESS) PostFilter(); if (key == GLFW_KEY_E && action == GLFW_PRESS) { last = true; DrawLine(oldMouseX, oldMouseY, FirstMouseX, FirstMouseY); } if (key == GLFW_KEY_C && action == GLFW_PRESS) Clear(); } static void mouse_callback(GLFWwindow* window, int button, int action, int mods) { if (button == GLFW_MOUSE_BUTTON_LEFT && oldMouseX != mouseX && oldMouseY != mouseY) { if (FirstMouseX == -1) { FirstMouseX = mouseX; FirstMouseY = mouseY; } SetPixel(mouseX, mouseY, 1); if (oldMouseX != -1) { DrawLine(oldMouseX, oldMouseY, mouseX, mouseY); } oldMouseX = mouseX; oldMouseY = mouseY; } if (button == GLFW_MOUSE_BUTTON_RIGHT) { } } static void cursor_callback(GLFWwindow* window, double x, double y) { mouseX = x; mouseY = y; } int main() { if (!glfwInit()) { cerr << "error in GLFW"; return -1; } window = glfwCreateWindow(Width, Height, "GL", NULL, NULL); if (window == NULL){ cerr << "Невозможно открыть окно GLFW. Если у вас Intel GPU, то он не поддерживает версию 3.3\n"; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glewExperimental = true; if (glewInit() != GLEW_OK) { cerr << "Невозможно инициализировать GLEW\n"; return -1; } for (int i = 0; i < Width; i++) { for (int j = 0; j < Height; j++) { SetPixel(i, Height - j, 0); } } glEnable(GL_DEPTH_TEST); glfwSetKeyCallback(window, keyboard_callback); glfwSetMouseButtonCallback(window, mouse_callback); glfwSetCursorPosCallback(window, cursor_callback); while (running) { GLint windowWidth, windowHeight; glfwGetWindowSize(window, &windowWidth, &windowHeight); glMatrixMode(GL_PROJECTION); glClearColor(0.0f, 0.0f, 0.25f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION_MATRIX); glLoadIdentity(); glDrawPixels(Width, Height, GL_RGB, GL_FLOAT, pixels); glfwSwapBuffers(window); glfwPollEvents(); } return 0; }