浏览代码

Merge pull request #7 from WalrusRPG/primitive

Lines and rectangle primitives, fills #6 requirement.


Streetwalrus is lazy.
Florian DORMONT 10 年之前
父节点
当前提交
f14ff7fdb3
共有 4 个文件被更改,包括 166 次插入26 次删除
  1. 29 1
      platform/include/Graphics.h
  2. 92 13
      platform/nspire/Graphics.cpp
  3. 44 12
      platform/sfml/Graphics.cpp
  4. 1 0
      src/utility/misc.h

+ 29 - 1
platform/include/Graphics.h

@@ -33,7 +33,7 @@ namespace WalrusRPG
         /*
          * Draws a sprite with clipping given as window.
          */
-        void put_sprite(const Texture &sheet, int x, int y,
+        void put_sprite(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
                         const WalrusRPG::Utils::Rect &window);
 
         /*
@@ -53,6 +53,34 @@ namespace WalrusRPG
          * Draws a pixel on the screen.
          */
         void put_pixel(uint16_t x, uint16_t y, const WalrusRPG::Graphics::Pixel &color);
+
+        // Primitives drawing
+
+        /*
+         * Draws an horizontal line on the screen.
+         */
+        void put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                 const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws an vertical line on the screen.
+         */
+        void put_vertical_line(uint16_t x, uint16_t y, uint16_t y2,
+                               const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws a line on the screen. As it uses Bresenham's algorithm, it won't be the
+         * most optimized way
+         * to draw vertical or horizontal lines.
+         */
+        void put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                      const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws a filled rectangle on the screen.
+         */
+        void put_rectangle(const WalrusRPG::Utils::Rect &rect,
+                           const WalrusRPG::Graphics::Pixel &color);
     }
 }
 

+ 92 - 13
platform/nspire/Graphics.cpp

@@ -1,50 +1,129 @@
 #include "Graphics.h"
 #include "CXfb.h"
 #include "stdio.h"
-
-#define GRAPHICS WalrusRPG::Graphics
+#include "utility/misc.h"
 
 using namespace Nspire;
+using namespace WalrusRPG;
+using WalrusRPG::Graphics::Texture;
+using WalrusRPG::Graphics::Pixel;
+using WalrusRPG::Utils::Rect;
 
-void GRAPHICS::init()
+void Graphics::init()
 {
     CXfb::buffer_allocate();
 }
 
-void GRAPHICS::deinit()
+void Graphics::deinit()
 {
     CXfb::buffer_free();
 }
 
-void GRAPHICS::frame_begin()
+void Graphics::frame_begin()
 {
 }
 
-void GRAPHICS::frame_end()
+void Graphics::frame_end()
 {
     CXfb::buffer_swap_render();
 }
 
-void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
-                          const WalrusRPG::Utils::Rect &window)
+void Graphics::put_sprite(const Texture &sheet, int x, int y, const Rect &window)
 {
     CXfb::draw_sprite_sheet(sheet.data, x, y, window);
 }
 
-void GRAPHICS::put_sprite_tint(const Texture &sheet, int x, int y,
-                               const WalrusRPG::Utils::Rect &window,
-                               const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_sprite_tint(const Texture &sheet, int x, int y, const Rect &window,
+                               const Pixel &color)
 {
     CXfb::draw_sprite_sheet_tint(sheet.data, x, y, window, color.value);
 }
 
-void GRAPHICS::fill(const WalrusRPG::Graphics::Pixel &color)
+void Graphics::fill(const Pixel &color)
 {
     CXfb::buffer_fill(color);
 }
 
-void GRAPHICS::put_pixel(uint16_t x, uint16_t y, const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_pixel(uint16_t x, uint16_t y, const Pixel &color)
 
 {
     CXfb::draw_pixel(x, y, color.value);
 }
+
+void Graphics::put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                   const Pixel &color)
+{
+    if (x > x2)
+    {
+        uint16_t temp = x;
+        x = x2;
+        x2 = temp;
+    }
+    for (; x < x2; x++)
+    {
+        CXfb::draw_pixel(x, y, color);
+    }
+}
+
+void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
+{
+    if (y > y2)
+    {
+        uint16_t temp = y;
+        y = y2;
+        y2 = temp;
+    }
+    for (; y < y2; y++)
+    {
+        CXfb::draw_pixel(x, y, color);
+    }
+}
+
+void Graphics::put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                        const Pixel &color)
+{
+    if (x == x2)
+    {
+        put_vertical_line(x, y, y2, color);
+        return;
+    }
+    else if (y == y2)
+    {
+        put_horizontal_line(x, x2, y, color);
+        return;
+    }
+    int dx = abs(x - x2), sx = x < x2 ? 1 : -1;
+    int dy = abs(y - y2), sy = y < y2 ? 1 : -1;
+    int err = (dx > dy ? dx : -dy) / 2, e2;
+
+    for (;;)
+    {
+        put_pixel(x, y, color);
+        if (x == x2 && y == y2)
+            break;
+        e2 = err;
+        if (e2 > -dx)
+        {
+            err -= dy;
+            x += sx;
+        }
+        if (e2 < dy)
+        {
+            err += dx;
+            y += sy;
+        }
+    }
+}
+
+void Graphics::put_rectangle(const Rect &rect, const Pixel &color)
+{
+    uint16_t xmax = min(320, rect.x + rect.width);
+    uint16_t ymax = min(240, rect.y + rect.height);
+    for (uint16_t x = rect.x; x < xmax; x++)
+    {
+        for (uint16_t y = rect.y; y < ymax; y++)
+        {
+            CXfb::draw_pixel(x, y, color.value);
+        }
+    }
+}

+ 44 - 12
platform/sfml/Graphics.cpp

@@ -3,13 +3,16 @@
 #include <SFML/Graphics.hpp>
 #include "utility/misc.h"
 
-#define GRAPHICS WalrusRPG::Graphics
+using namespace WalrusRPG;
+using WalrusRPG::Graphics::Texture;
+using WalrusRPG::Graphics::Pixel;
+using WalrusRPG::Utils::Rect;
 
 sf::RenderWindow window;
 sf::View view;
 sf::RenderTexture buffer;
 
-void GRAPHICS::init()
+void Graphics::init()
 {
     // window.create(sf::VideoMode::getDesktopMode(), "WalrusRPG", sf::Style::Fullscreen);
     window.create(sf::VideoMode(640, 480), "WalrusRPG");
@@ -18,17 +21,17 @@ void GRAPHICS::init()
     buffer.create(320, 240);
 }
 
-void GRAPHICS::deinit()
+void Graphics::deinit()
 {
     window.close();
 }
 
-void GRAPHICS::frame_begin()
+void Graphics::frame_begin()
 {
     window.clear(sf::Color::Black);
 }
 
-void GRAPHICS::frame_end()
+void Graphics::frame_end()
 {
     sf::Sprite sprite(buffer.getTexture());
     sf::Vector2u winsize = window.getSize();
@@ -49,8 +52,8 @@ void GRAPHICS::frame_end()
     window.display();
 }
 
-void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
-                          const WalrusRPG::Utils::Rect &window)
+void Graphics::put_sprite(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
+                          const Rect &window)
 {
     sf::Sprite sprite;
     sprite.setTexture(sheet.data);
@@ -59,9 +62,8 @@ void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
     buffer.draw(sprite);
 }
 
-void GRAPHICS::put_sprite_tint(const Texture &sheet, int x, int y,
-                               const WalrusRPG::Utils::Rect &window,
-                               const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_sprite_tint(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
+                               const Rect &window, const Pixel &color)
 {
     sf::Sprite sprite;
     sprite.setTexture(sheet.data);
@@ -71,12 +73,12 @@ void GRAPHICS::put_sprite_tint(const Texture &sheet, int x, int y,
     buffer.draw(sprite);
 }
 
-void GRAPHICS::fill(const WalrusRPG::Graphics::Pixel &color)
+void Graphics::fill(const Pixel &color)
 {
     buffer.clear(sf::Color(color.r << 3, color.g << 2, color.b << 2, 255));
 }
 
-void GRAPHICS::put_pixel(uint16_t x, uint16_t y, const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_pixel(uint16_t x, uint16_t y, const Pixel &color)
 {
     sf::RectangleShape pixel;
     pixel.setSize(sf::Vector2f(1, 1));
@@ -84,3 +86,33 @@ void GRAPHICS::put_pixel(uint16_t x, uint16_t y, const WalrusRPG::Graphics::Pixe
     pixel.setPosition(x, y);
     buffer.draw(pixel);
 }
+
+void Graphics::put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                   const Pixel &color)
+{
+    put_line(x, y, x2, y, color);
+}
+
+void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
+{
+    put_line(x, y, x, y2, color);
+}
+
+void Graphics::put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                        const Pixel &color)
+{
+    sf::Color lineColor(color.r << 3, color.g << 2, color.b << 3);
+    sf::Vertex line[] = {sf::Vertex(sf::Vector2f(x, y), lineColor),
+                         sf::Vertex(sf::Vector2f(x2, y2), lineColor)};
+
+    buffer.draw(line, 2, sf::Lines);
+}
+
+void Graphics::put_rectangle(const Rect &rect, const Pixel &color)
+{
+    sf::RectangleShape rectangle;
+    rectangle.setSize(sf::Vector2f(rect.width, rect.height));
+    rectangle.setFillColor(sf::Color(color.r << 3, color.g << 2, color.b << 3));
+    rectangle.setPosition(rect.x, rect.y);
+    buffer.draw(rectangle);
+}

+ 1 - 0
src/utility/misc.h

@@ -3,6 +3,7 @@
 
 #define UNUSED(expr) (void)(expr)
 
+#define abs(x) ((x) < 0 ? -(x) : (x))
 #define min(a, b) (((a) < (b)) ? (a) : (b))
 #define max(a, b) (((a) > (b)) ? (a) : (b))