Просмотр исходного кода

Lines and rectangle primitives, fills #6 requirement

Eiyeron Fulmincendii лет назад: 10
Родитель
Сommit
9c144fdda9
4 измененных файлов с 153 добавлено и 26 удалено
  1. 24 1
      platform/include/Graphics.h
  2. 80 13
      platform/nspire/Graphics.cpp
  3. 48 12
      platform/sfml/Graphics.cpp
  4. 1 0
      src/utility/misc.h

+ 24 - 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,29 @@ 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);
     }
 }
 

+ 80 - 13
platform/nspire/Graphics.cpp

@@ -1,50 +1,117 @@
 #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);
+        }
+    }
+}

+ 48 - 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,9 @@ 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 +74,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 +87,36 @@ 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))