#include "rasterize.hh" #include #include #include class Slope { float begin, step; public: Slope() {} Slope(float from, float to, int num_steps) { float inv_step = 1.f / num_steps; begin = from; // Begin here step = (to - from) * inv_step; // Stepsize = (end-begin) / num_steps } float get() const { return begin; } void advance() { begin += step; } }; template void DrawFilledSingleColorPolygon( std::array p0, std::array p1, std::array p2, PlotFunc&& Plot) { using SlopeData = Slope; RasterizeTriangle( &p0, &p1, &p2, // GetXY: Retrieve std::tuple or std::array from a PointType [&](const auto& p) { return p; }, // Slope generator [&](const std::array* from, const std::array* to, int num_steps) { // Retrieve X coordinates for begin and end. // Number of steps = number of scanlines return SlopeData( (*from)[0], (*to)[0], num_steps ); }, // Scanline function [&](int y, SlopeData& left, SlopeData& right) { int x = left.get(), endx = right.get(); for(; x < endx; ++x) // Render each pixel { Plot(x, y); } // After the scanline is drawn, update the X coordinate on both sides left.advance(); right.advance(); }); } #include "mesh.hh" #include int main() { const int W = 424, H = 240; // Create a screen. SDL_Window* window = SDL_CreateWindow("Chip8", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, W*4,H*4, SDL_WINDOW_RESIZABLE); SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0); SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, W,H); // Create a mesh of triangles covering the entire screen std::vector< std::array, 3> > triangles = CreateTriangleMesh(W,H,100); for(bool interrupted=false; !interrupted; ) { // Process events. SDL_Event ev; while(SDL_PollEvent(&ev)) switch(ev.type) { case SDL_QUIT: interrupted = true; break; } // Render graphics Uint32 pixels[W*H]={}; unsigned color = 0x3B0103A5, blank = 0xFFFFFF, duplicate = 0xFFAA55; for(auto& p: pixels) p = blank; for(auto& t: triangles) { color = ((color << 1) | (color >> (32-1))); DrawFilledSingleColorPolygon( t[0], t[1], t[2], [&](int x,int y) { if(pixels[y*W+x] != blank) pixels[y*W+x] = duplicate; else pixels[y*W+x] = (color&0xFFFFFF); }); } SDL_UpdateTexture(texture, nullptr, pixels, 4*W); SDL_RenderCopy(renderer, texture, nullptr, nullptr); SDL_RenderPresent(renderer); SDL_Delay(1000/60); } }