[FEAT] Add canvas ppm part.
This commit is contained in:
49
data/canvas.ppm
Normal file
49
data/canvas.ppm
Normal file
@@ -0,0 +1,49 @@
|
||||
P3
|
||||
# Created by GIMP version 2.10.30 PNM plug-in
|
||||
5 3
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
255
|
||||
255
|
||||
255
|
||||
0
|
||||
0
|
||||
0
|
||||
@@ -78,3 +78,59 @@ bool Canvas::write_pixel(uint16_t a_pos_x, uint16_t a_pos_y, const Color &a_colo
|
||||
m_pixels[a_pos_x][a_pos_y] = a_color;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
std::string Canvas::to_ppm(void)
|
||||
{
|
||||
std::string the_result;
|
||||
|
||||
// Header
|
||||
the_result = "P3\n";
|
||||
the_result += std::to_string(m_width) + " " + std::to_string(m_height) + "\n";
|
||||
the_result += "255\n";
|
||||
|
||||
for (int j = 0; j < m_height; j++)
|
||||
{
|
||||
uint16_t the_col_number = 0;
|
||||
for (int i = 0; i < m_width; i++)
|
||||
{
|
||||
Color the_color;
|
||||
the_color = m_pixels[i][j];
|
||||
|
||||
add_color_component(the_result, the_col_number, the_color.red_to_integer());
|
||||
add_color_component(the_result, the_col_number, the_color.green_to_integer());
|
||||
add_color_component(the_result, the_col_number, the_color.blue_to_integer());
|
||||
}
|
||||
the_result += "\n";
|
||||
the_col_number = 0;
|
||||
}
|
||||
|
||||
return the_result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Canvas::add_color_component(std::string &a_str_value, uint16_t &a_col_number, uint8_t a_color)
|
||||
{
|
||||
std::string the_color_value;
|
||||
|
||||
the_color_value = std::to_string(a_color);
|
||||
|
||||
if ((the_color_value.length() + 1 + a_col_number) >= 70)
|
||||
{
|
||||
a_str_value += "\n";
|
||||
a_col_number = 0;
|
||||
}
|
||||
|
||||
if (a_col_number != 0)
|
||||
{
|
||||
a_str_value += " ";
|
||||
a_col_number++;
|
||||
}
|
||||
|
||||
a_str_value += the_color_value;
|
||||
a_col_number += the_color_value.length();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,9 +28,11 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "color.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -49,6 +51,11 @@ namespace Raytracer
|
||||
const Color &pixel_at(uint16_t a_pos_x, uint16_t a_pos_y) const;
|
||||
bool write_pixel(uint16_t a_pos_x, uint16_t a_pos_y, const Color &a_color);
|
||||
|
||||
std::string to_ppm(void);
|
||||
|
||||
private:
|
||||
bool add_color_component(std::string &a_str_value, uint16_t &a_col_number, uint8_t a_color);
|
||||
|
||||
private:
|
||||
uint16_t m_width;
|
||||
uint16_t m_height;
|
||||
|
||||
@@ -28,13 +28,14 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
#include "common.h"
|
||||
#include "color.h"
|
||||
|
||||
using namespace Raytracer;
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Color::Color(void) : m_red(0), m_green(0), m_blue(0)
|
||||
@@ -174,3 +175,46 @@ double Color::blue(void) const
|
||||
{
|
||||
return m_blue;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
uint8_t Color::red_to_integer(void) const
|
||||
{
|
||||
return color_to_integer(m_red);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
uint8_t Color::green_to_integer(void) const
|
||||
{
|
||||
return color_to_integer(m_green);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
uint8_t Color::blue_to_integer(void) const
|
||||
{
|
||||
return color_to_integer(m_blue);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
uint8_t Color::color_to_integer(double a_color) const
|
||||
{
|
||||
uint8_t the_value;
|
||||
|
||||
if (a_color < 0)
|
||||
{
|
||||
the_value = 0;
|
||||
}
|
||||
else if (a_color > 1.0)
|
||||
{
|
||||
the_value = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
the_value = round(a_color * 255);
|
||||
}
|
||||
|
||||
return the_value;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
namespace Raytracer
|
||||
{
|
||||
class Color
|
||||
@@ -55,6 +59,13 @@ namespace Raytracer
|
||||
double green(void) const;
|
||||
double blue(void) const;
|
||||
|
||||
uint8_t red_to_integer(void) const;
|
||||
uint8_t green_to_integer(void) const;
|
||||
uint8_t blue_to_integer(void) const;
|
||||
|
||||
private:
|
||||
uint8_t color_to_integer(double a_color) const;
|
||||
|
||||
private:
|
||||
double m_red;
|
||||
double m_green;
|
||||
|
||||
@@ -56,3 +56,53 @@ TEST_CASE("[Canvas] Writing pixels to a canvas", "[Canvas]")
|
||||
|
||||
REQUIRE(c.pixel_at(2, 3) == red);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[Canvas] Constructing the PPM pixel data", "[Canvas]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
Canvas c(5, 3);
|
||||
Color c1(1.5, 0, 0);
|
||||
Color c2(0, 0.5, 0);
|
||||
Color c3(-0.5, 0, 1);
|
||||
|
||||
c.write_pixel(0, 0, c1);
|
||||
c.write_pixel(2, 1, c2);
|
||||
c.write_pixel(4, 2, c3);
|
||||
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n5 3\n255\n";
|
||||
the_ref_ppm += "255 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 128 0 0 0 0 0 0 0\n";
|
||||
the_ref_ppm += "0 0 0 0 0 0 0 0 0 0 0 0 0 0 255\n";
|
||||
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[Canvas] Split long lines in PPM files", "[Canvas]")
|
||||
{
|
||||
std::string ppm, the_ref_ppm;
|
||||
Canvas c(10, 2);
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
c.write_pixel(i, j, Color(1, 0.8, 0.6));
|
||||
}
|
||||
}
|
||||
|
||||
ppm = c.to_ppm();
|
||||
|
||||
the_ref_ppm = "P3\n10 2\n255\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
the_ref_ppm += "255 204 153 255 204 153 255 204 153 255 204 153 255 204 153 255 204\n";
|
||||
the_ref_ppm += "153 255 204 153 255 204 153 255 204 153 255 204 153\n";
|
||||
|
||||
REQUIRE(ppm == the_ref_ppm);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user