From 653f6e9f88ab6712598fd633d39e4731c7a254cc Mon Sep 17 00:00:00 2001 From: blobt <380255922@qq.com> Date: Thu, 30 Jan 2020 14:03:27 +0800 Subject: [PATCH] draw rect --- src/CMakeLists.txt | 3 ++ src/Raster.cc | 38 ++++++++++++-------- src/Raster.h | 1 + src/common.h | 9 +++++ src/draw_rect.cc | 86 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 src/draw_rect.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 28fba3e..2326cfb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,6 @@ +add_executable(draw_rect draw_rect.cc ${commom_src}) +target_link_libraries (draw_rect ${FC_DEP_LIBS}) + add_executable(draw_filled_rect draw_filled_rect.cc ${commom_src}) target_link_libraries (draw_filled_rect ${FC_DEP_LIBS}) diff --git a/src/Raster.cc b/src/Raster.cc index 41f0a3f..f80f406 100644 --- a/src/Raster.cc +++ b/src/Raster.cc @@ -195,25 +195,35 @@ void Raster::drawArray(DRAWMODE mode, const float2* points, size_t count) { void Raster::drawFilledRect(int startX, int startY, int width, int height) { /*越界部分不描画*/ - if (startX < 0) { - startX = 0; - } + int left = tmax(startX, 0); + int bottom = tmax(startY, 0); - if (startY < 0) { - startY = 0; - } + int right = tmin(startX + width, _width); + int top = tmin(startY + height, _height); - if (startX + width > _width) { - width = _width - startX; + for (int x = left; x < right; x++) { + for (int y = bottom; y < top; y++) { + drawPoint(x, y, Rgba(255, 0, 0, 0)); + } } +} - if (startY + height > _height) { - height = _height - startY; - } +void Raster::drawRect(const int2* points, const Rgba* colors) { + int left = tmax(points[0].x, 0); + int bottom = tmax(points[0].y, 0); - 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 right = tmin(points[2].x, _width); + int top = tmin(points[2].y, _height); + + float w = right - left; + float h = top - bottom; + + for (int x = left; x < right; ++x) { + Rgba color1 = colorLerp(colors[0], colors[1], (x - left) / w); + Rgba color2 = colorLerp(colors[3], colors[2], (x - left) / w); + for (int y = bottom; y < top; ++y) { + Rgba color = colorLerp(color1, color2, (y - bottom) / h); + drawPoint(x, y, color); } } } diff --git a/src/Raster.h b/src/Raster.h index d5ed6fa..ab2dab2 100644 --- a/src/Raster.h +++ b/src/Raster.h @@ -33,6 +33,7 @@ public: 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); + void drawRect(const int2* points, const Rgba* colors); int size(); void clean(); bool setPixel(int x, int y, Rgba color); diff --git a/src/common.h b/src/common.h index 79033a3..52dedc2 100644 --- a/src/common.h +++ b/src/common.h @@ -20,6 +20,14 @@ #define die(m) do { perror(m); exit(EXIT_FAILURE); } while(0) #define def2rad(theta) (0.01745329251994329 * (theta)) //每个角度所对应的弧度 +template inline T tmin(T a, T b) { + return a < b ? a : b; +} + +template inline T tmax(T a, T b) { + return a > b ? a : b; +} + template struct tvec2 { typedef T value_type; @@ -56,6 +64,7 @@ struct tvec2 { typedef tvec2 float2; +typedef tvec2 int2; #endif /* COMMON_H */ diff --git a/src/draw_rect.cc b/src/draw_rect.cc new file mode 100644 index 0000000..9d6a944 --- /dev/null +++ b/src/draw_rect.cc @@ -0,0 +1,86 @@ +#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(); + + for (int i = 0; i < 10000; i++) { + raster.drawPoint(rand() % height, rand() % width, Rgba(255, 0, 0), 3); + } + + int2 points[] = { + int2(50, 50), + int2(250, 50), + int2(250, 250), + int2(50, 250) + }; + + Rgba colors[] = { + Rgba(255, 0, 0, 0), + Rgba(0, 255, 0, 0), + Rgba(0, 0, 255, 0), + Rgba(255, 255, 255, 0), + }; + + raster.drawRect(points, colors); + + 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; +}