Skip to content

Instantly share code, notes, and snippets.

@axjxwright
Created April 5, 2016 07:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save axjxwright/f8324f1e5cb791d8a286aaf5de806193 to your computer and use it in GitHub Desktop.
Save axjxwright/f8324f1e5cb791d8a286aaf5de806193 to your computer and use it in GitHub Desktop.
#include "draw.h"
#include <fstream>
#include <cmath>
#include <cassert>
namespace lithium
{
Surface::Surface ( std::uint32_t w, std::uint32_t h, const Color& bg )
: _width ( w )
, _height ( h )
{
_data = std::vector<Color> ( w * h, bg );
}
void Surface::SetPixel ( std::uint32_t x, std::uint32_t y, std::uint8_t r, std::uint8_t g, std::uint8_t b )
{
SetPixel ( x, y, Color ( r, g, b ) );
}
void Surface::SetPixel ( std::uint32_t x, std::uint32_t y, const Color& color )
{
#ifndef NDEGUG
assert ( x >= 0 );
assert ( y >= 0 );
assert ( x < _width );
assert ( y < _height );
#endif
_data[x * _height + y] = color;
}
Color Surface::GetPixel ( std::uint32_t x, std::uint32_t y ) const
{
return _data[x * _height + y];
}
void Surface::Line ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, const Color& color )
{
std::int32_t dx = abs ( x1 - x0 );
std::int32_t sx = x0 < x1 ? 1 : -1;
std::int32_t dy = abs ( y1 - y0 );
std::int32_t sy = y0 < y1 ? 1 : -1;
std::int32_t error = (dx > dy ? dx : -dy ) / 2;
std::int32_t error2;
for( ;; )
{
SetPixel ( x0, y0, color );
if (x0 == x1 && y0 == y1 ) break;
error2 = error;
if ( error2 > -dx ) { error -= dy; x0 += sx; }
if ( error2 < dy ) { error += dx; y0 += sy; }
}
}
void Surface::WritePPM ( std::ostream& stream )
{
stream << "P6 ";
stream << _width << " " << _height << " ";
stream << "255 ";
for ( std::uint32_t y = 0; y < _height; y++ )
{
for ( std::uint32_t x = 0; x < _width; x++ )
{
auto c = GetPixel ( x, y );
stream << c.R << c.G << c.B;
}
}
}
}
#include <iostream>
#include <vector>
#include <cstdint>
namespace lithium
{
struct Color
{
std::uint8_t R, G, B;
Color ( )
: R(0)
, G(0)
, B(0)
{ }
Color ( std::uint8_t r, std::uint8_t g, std::uint8_t b )
: R(r)
, G(g)
, B(b)
{ }
};
class Surface
{
public:
Surface ( ) { };
Surface ( std::uint32_t w, std::uint32_t h, const Color& bg = Color ( 0, 0, 0 ) );
std::uint32_t Width ( ) const { return _width; }
std::uint32_t Height ( ) const { return _height; }
const std::vector<Color>& Data ( ) const { return _data; };
void Line ( std::int32_t x0, std::int32_t y0, std::int32_t x1, std::int32_t y1, const Color& color );
void SetPixel ( std::uint32_t x, std::uint32_t y, std::uint8_t r, std::uint8_t g, std::uint8_t b );
void SetPixel ( std::uint32_t x, std::uint32_t y, const Color& color );
Color GetPixel ( std::uint32_t x, std::uint32_t y ) const;
void WritePPM ( std::ostream& stream );
protected:
std::uint32_t _width{0}, _height{0};
std::vector<Color> _data;
};
}
all:
clang++ *.cxx -std=c++1y -stdlib=libc++ -O3 -o draw
#include <fstream>
#include "draw.h"
std::vector<float> getRandomSamples ( int count )
{
std::vector<float> result;
for ( int i = 0; i < count; i++ )
{
float r = static_cast <float> ( rand() ) / static_cast <float> (RAND_MAX);
result.push_back ( r );
}
return result;
}
int main ()
{
using namespace lithium;
std::vector<float> samples = getRandomSamples( 512 );
Color grey ( 32, 32, 32 );
Color blue ( 0, 64, 255 );
Surface image ( samples.size(), 256, grey );
int lastY = 0;
for ( int i = 0; i < samples.size() - 1; i++ )
{
int x0 = i, x1 = i + 1;
float ratio = samples[i];
int y0 = lastY;
int y1 = ratio * image.Height();
image.Line ( x0, y0, x1, y1, blue );
lastY = y1;
}
std::ofstream file ( "image.ppm" );
image.WritePPM ( file );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment