From 359db9d64de60b0d90d2ee9cfd8b1722d8367199 Mon Sep 17 00:00:00 2001 From: blobt <380255922@qq.com> Date: Thu, 30 Jan 2020 11:44:51 +0800 Subject: [PATCH] draw rect --- CMakeLists.txt | 5 ++ src/CMakeLists.txt | 11 +++- src/{Rester.cc => Raster.cc} | 50 ++++++++++++----- src/{Rester.h => Raster.h} | 7 +-- src/draw_filled_rect.cc | 68 +++++++++++++++++++++++ src/drawbezzier.cc | 95 ++++++++++++++++++++++++++++++++ src/drawline.cc | 102 +++++++++++++++++++++++++++++++++++ src/gtktest.cc | 18 +++---- 8 files changed, 331 insertions(+), 25 deletions(-) rename src/{Rester.cc => Raster.cc} (81%) rename src/{Rester.h => Raster.h} (86%) create mode 100644 src/draw_filled_rect.cc create mode 100644 src/drawbezzier.cc create mode 100644 src/drawline.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 061b067..bce3a1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,5 +15,10 @@ include_directories(${GTK2_INCLUDE_DIRS}) link_directories(${GTK2_LIBRARY_DIRS}) list(APPEND FC_DEP_LIBS ${GTK2_LIBRARIES}) +set(commom_src + Rgba.cc + Raster.cc +) + add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c0c21b7..28fba3e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,13 @@ -add_executable(gtktest gtktest.cc Rgba.cc Rester.cc) +add_executable(draw_filled_rect draw_filled_rect.cc ${commom_src}) +target_link_libraries (draw_filled_rect ${FC_DEP_LIBS}) + +add_executable(drawbezzier drawbezzier.cc ${commom_src}) +target_link_libraries (drawbezzier ${FC_DEP_LIBS}) + +add_executable(drawline drawline.cc ${commom_src}) +target_link_libraries (drawline ${FC_DEP_LIBS}) + +add_executable(gtktest gtktest.cc ${commom_src}) target_link_libraries (gtktest ${FC_DEP_LIBS}) add_executable(timer timer.cc) diff --git a/src/Rester.cc b/src/Raster.cc similarity index 81% rename from src/Rester.cc rename to src/Raster.cc index 523d41c..41f0a3f 100644 --- a/src/Rester.cc +++ b/src/Raster.cc @@ -5,14 +5,14 @@ */ /* - * File: Rester.cc + * File: Raster.cc * Author: blobt * * Created on January 23, 2020, 6:00 PM */ #include "Rgba.h" -#include "Rester.h" +#include "Raster.h" #include #include #include @@ -20,18 +20,18 @@ using namespace std; -Rester::Rester(int width, int height) { +Raster::Raster(int width, int height) { _width = width; _height = height; buffer = new Rgba[width * height]; } -Rester::~Rester() { +Raster::~Raster() { delete buffer; } -void Rester::drawPoint(int x, int y, Rgba color, int pointSize) { +void Raster::drawPoint(int x, int y, Rgba color, int pointSize) { switch (pointSize) { case 1: setPixel(x, y, color); @@ -55,7 +55,7 @@ void Rester::drawPoint(int x, int y, Rgba color, int pointSize) { } } -void Rester::drawLine(float2 p1, float2 p2, Rgba color) { +void Raster::drawLine(float2 p1, float2 p2, Rgba color) { float xOffer = p1.x - p2.x; float yOffer = p1.y - p2.y; @@ -101,7 +101,7 @@ void Rester::drawLine(float2 p1, float2 p2, Rgba color) { } -void Rester::drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2) { +void Raster::drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2) { float xOffer = p1.x - p2.x; float yOffer = p1.y - p2.y; @@ -154,7 +154,7 @@ void Rester::drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2) { } -void Rester::drawArray(DRAWMODE mode, const float2* points, size_t count) { +void Raster::drawArray(DRAWMODE mode, const float2* points, size_t count) { switch (mode) { case DM_POINTS: { @@ -166,7 +166,7 @@ void Rester::drawArray(DRAWMODE mode, const float2* points, size_t count) { case DM_LINES: { count = count / 2 * 2; //保证其为2的倍数 - for (size_t i = 0; i < count; i++) { + for (size_t i = 0; i < count; i += 2) { drawLine(points[i], points[i + 1]); } } @@ -192,15 +192,41 @@ void Rester::drawArray(DRAWMODE mode, const float2* points, size_t count) { }; } -int Rester::size() { +void Raster::drawFilledRect(int startX, int startY, int width, int height) { + + /*越界部分不描画*/ + if (startX < 0) { + startX = 0; + } + + if (startY < 0) { + startY = 0; + } + + if (startX + width > _width) { + width = _width - startX; + } + + if (startY + height > _height) { + height = _height - startY; + } + + for (int x = startX; x < startX + width; x++) { + for (int y = startY; y < startY + height; y++) { + drawPoint(x, y, Rgba(255, 0, 0, 0)); + } + } +} + +int Raster::size() { return _width * _height * sizeof (Rgba); } -void Rester::clean() { +void Raster::clean() { memset(buffer, 0, size()); } -bool Rester::setPixel(int x, int y, Rgba color) { +bool Raster::setPixel(int x, int y, Rgba color) { if (x < 0 || y < 0 || x >= _width || y >= _height) { return false; } diff --git a/src/Rester.h b/src/Raster.h similarity index 86% rename from src/Rester.h rename to src/Raster.h index 1e36132..d5ed6fa 100644 --- a/src/Rester.h +++ b/src/Raster.h @@ -23,15 +23,16 @@ enum DRAWMODE { DM_LINES_TRIP = 3 }; -class Rester { +class Raster { public: Rgba* buffer; - Rester(int width, int height); - virtual ~Rester(); + Raster(int width, int height); + virtual ~Raster(); void drawPoint(int x, int y, Rgba color = Rgba(255, 0, 0, 0), int pointSize = 1); void drawLine(float2 p1, float2 p2, Rgba color = Rgba(255, 0, 0, 0)); void drawLine(float2 p1, float2 p2, Rgba color1, Rgba color2); void drawArray(DRAWMODE mode, const float2* points, size_t count); + void drawFilledRect(int startX, int startY, int width, int height); int size(); void clean(); bool setPixel(int x, int y, Rgba color); diff --git a/src/draw_filled_rect.cc b/src/draw_filled_rect.cc new file mode 100644 index 0000000..be119a3 --- /dev/null +++ b/src/draw_filled_rect.cc @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include "Rgba.h" +#include "Raster.h" +#include "common.h" + +using namespace std; + + +gint height = 500; +gint width = 500; + +Raster raster(width, height); + +unsigned char* makeBitmap() { + raster.clean(); + + raster.drawFilledRect(100, 100, 150, 500); + + return (unsigned char*) raster.buffer; +} + +void render(GtkWidget *widget) { + //允许窗口可以绘图 + gtk_widget_set_app_paintable(widget, TRUE); + gtk_widget_realize(widget); + gtk_widget_queue_draw(widget); + + //模拟一张图片 + unsigned char* data = makeBitmap(); + + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); + + GdkPixmap *pixmap = NULL; + + gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 128); + + gdk_window_set_back_pixmap(widget->window, pixmap, FALSE); + + g_object_unref(pixbuf); + g_object_unref(pixmap); + //delete data; +} + +int main(int argc, char* argv[]) { + + gtk_init(&argc, &argv); + + //创建窗口 + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(window, width, height); + + gtk_window_set_title(GTK_WINDOW(window), "Gtk testing"); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); + + //窗口关闭时候,关闭程序 + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + //设置渲染 + g_signal_connect(window, "expose-event", G_CALLBACK(render), window); + + + gtk_widget_show_all(window); + gtk_main(); + + return 0; +} diff --git a/src/drawbezzier.cc b/src/drawbezzier.cc new file mode 100644 index 0000000..0d616fd --- /dev/null +++ b/src/drawbezzier.cc @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include "Rgba.h" +#include "Raster.h" +#include "common.h" + +using namespace std; + + +gint height = 500; +gint width = 500; + +Raster rester(width, height); + +unsigned char* makeBitmap() { + rester.clean(); + + /*贝塞尔的4个点*/ + float2 points[] = { + float2(50, 50), + float2(200, 50), + float2(33, 88), + float2(159, 100) + }; + + /*划线的两个点*/ + float2 actPoint[2]; + + for (float t = 0; t < 1; t += 0.01f) { + float x = points[0].x * pow(1 - t, 3) + + 3 * points[1].x * t * pow(1 - t, 2) + + 3 * points[2].x * t * t * (1 - t) + + points[3].x * t * t * t; + float y = points[0].y * pow(1 - t, 3) + + 3 * points[1].y * t * pow(1 - t, 2) + + 3 * points[2].y * t * t * (1 - t) + + points[3].y * t * t * t; + if (t == 0) { + actPoint[0] = float2(x, y); + } else { + actPoint[1] = float2(x, y); + rester.drawArray(DM_LINES, actPoint, 2); + actPoint[0] = actPoint[1]; + } + } + + return (unsigned char*) rester.buffer; +} + +void render(GtkWidget *widget) { + //允许窗口可以绘图 + gtk_widget_set_app_paintable(widget, TRUE); + gtk_widget_realize(widget); + gtk_widget_queue_draw(widget); + + //模拟一张图片 + unsigned char* data = makeBitmap(); + + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); + + GdkPixmap *pixmap = NULL; + + gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 128); + + gdk_window_set_back_pixmap(widget->window, pixmap, FALSE); + + g_object_unref(pixbuf); + g_object_unref(pixmap); + //delete data; +} + +int main(int argc, char* argv[]) { + + gtk_init(&argc, &argv); + + //创建窗口 + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(window, width, height); + + gtk_window_set_title(GTK_WINDOW(window), "Gtk testing"); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); + + //窗口关闭时候,关闭程序 + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + //设置渲染 + g_signal_connect(window, "expose-event", G_CALLBACK(render), window); + + + gtk_widget_show_all(window); + gtk_main(); + + return 0; +} diff --git a/src/drawline.cc b/src/drawline.cc new file mode 100644 index 0000000..515def3 --- /dev/null +++ b/src/drawline.cc @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include "Rgba.h" +#include "Raster.h" +#include "common.h" + +using namespace std; + + +gint height = 500; +gint width = 500; + +Raster raster(width, height); + +unsigned char* makeBitmapRand() { + unsigned char* data = new unsigned char[width * height * 4]; + for (int i = 0; i < width * height * 4; i++) { + data[i] = rand() % 255; + } + return data; +} + +unsigned char* makeBitmap() { + raster.clean(); + + for (int i = 0; i < 100; i++) { + raster.drawPoint(rand() % height, rand() % width, Rgba(255, 0, 0), 3); + } + + raster.drawLine(float2(100, 100), float2(100, 222), Rgba(255, 0, 0)); + raster.drawLine(float2(100, 100), float2(400, 400), Rgba(255, 0, 0), Rgba(0, 255, 0)); + + + float2 arrPoints[] = { + float2(11, 34), + float2(33, 66), + float2(1, 100), + float2(22, 88), + float2(100, 1) + }; + + raster.drawArray(DM_LINES_TRIP, arrPoints, sizeof (arrPoints) / sizeof (arrPoints[0])); + + float2 center(250, 250); + float radius = 80; + float2 arrCircle[360]; + + for (int i = 0; i < 180; i++) { + arrCircle[i].x = radius * cos(def2rad(i)) + center.x; + arrCircle[i].y = radius * sin(def2rad(i)) + center.y; + } + raster.drawArray(DM_LINES_TRIP, arrCircle, sizeof (arrCircle) / sizeof (arrCircle[0])); + + return (unsigned char*) raster.buffer; +} + +void render(GtkWidget *widget) { + //允许窗口可以绘图 + gtk_widget_set_app_paintable(widget, TRUE); + gtk_widget_realize(widget); + gtk_widget_queue_draw(widget); + + //模拟一张图片 + unsigned char* data = makeBitmap(); + + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); + + GdkPixmap *pixmap = NULL; + + gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 128); + + gdk_window_set_back_pixmap(widget->window, pixmap, FALSE); + + g_object_unref(pixbuf); + g_object_unref(pixmap); + //delete data; +} + +int main(int argc, char* argv[]) { + + gtk_init(&argc, &argv); + + //创建窗口 + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(window, width, height); + + gtk_window_set_title(GTK_WINDOW(window), "Gtk testing"); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); + + //窗口关闭时候,关闭程序 + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + //设置渲染 + g_signal_connect(window, "expose-event", G_CALLBACK(render), window); + + + gtk_widget_show_all(window); + gtk_main(); + + return 0; +} diff --git a/src/gtktest.cc b/src/gtktest.cc index 25244f5..515def3 100644 --- a/src/gtktest.cc +++ b/src/gtktest.cc @@ -3,7 +3,7 @@ #include #include #include "Rgba.h" -#include "Rester.h" +#include "Raster.h" #include "common.h" using namespace std; @@ -12,7 +12,7 @@ using namespace std; gint height = 500; gint width = 500; -Rester rester(width, height); +Raster raster(width, height); unsigned char* makeBitmapRand() { unsigned char* data = new unsigned char[width * height * 4]; @@ -23,14 +23,14 @@ unsigned char* makeBitmapRand() { } unsigned char* makeBitmap() { - rester.clean(); + raster.clean(); for (int i = 0; i < 100; i++) { - rester.drawPoint(rand() % height, rand() % width, Rgba(255, 0, 0), 3); + raster.drawPoint(rand() % height, rand() % width, Rgba(255, 0, 0), 3); } - rester.drawLine(float2(100, 100), float2(100, 222), Rgba(255, 0, 0)); - rester.drawLine(float2(100, 100), float2(400, 400), Rgba(255, 0, 0), Rgba(0, 255, 0)); + raster.drawLine(float2(100, 100), float2(100, 222), Rgba(255, 0, 0)); + raster.drawLine(float2(100, 100), float2(400, 400), Rgba(255, 0, 0), Rgba(0, 255, 0)); float2 arrPoints[] = { @@ -41,7 +41,7 @@ unsigned char* makeBitmap() { float2(100, 1) }; - rester.drawArray(DM_LINES_TRIP, arrPoints, sizeof (arrPoints) / sizeof (arrPoints[0])); + raster.drawArray(DM_LINES_TRIP, arrPoints, sizeof (arrPoints) / sizeof (arrPoints[0])); float2 center(250, 250); float radius = 80; @@ -51,9 +51,9 @@ unsigned char* makeBitmap() { arrCircle[i].x = radius * cos(def2rad(i)) + center.x; arrCircle[i].y = radius * sin(def2rad(i)) + center.y; } - rester.drawArray(DM_LINES_TRIP, arrCircle, sizeof (arrCircle) / sizeof (arrCircle[0])); + raster.drawArray(DM_LINES_TRIP, arrCircle, sizeof (arrCircle) / sizeof (arrCircle[0])); - return (unsigned char*) rester.buffer; + return (unsigned char*) raster.buffer; } void render(GtkWidget *widget) {