RasterDrawMethods CRTP, PlaneAdapters in VideoBuffer, Graphics, and Renderer
This commit is contained in:
parent
a0a9ad0abd
commit
e93db9c06a
@ -41,7 +41,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
auto rng = std::make_unique<RNG>();
|
auto rng = std::make_unique<RNG>();
|
||||||
Simulation * sim = new Simulation();
|
Simulation * sim = new Simulation();
|
||||||
Renderer * ren = new Renderer(new Graphics(), sim);
|
Renderer * ren = new Renderer(sim);
|
||||||
|
|
||||||
if (gameSave)
|
if (gameSave)
|
||||||
{
|
{
|
||||||
@ -57,7 +57,7 @@ int main(int argc, char *argv[])
|
|||||||
frame--;
|
frame--;
|
||||||
ren->render_parts();
|
ren->render_parts();
|
||||||
ren->render_fire();
|
ren->render_fire();
|
||||||
ren->clearScreen(1.0f);
|
ren->clearScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -17,6 +17,9 @@ struct extentStorage
|
|||||||
{
|
{
|
||||||
return Extent;
|
return Extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr void setExtent(size_t)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@ -32,6 +35,11 @@ struct extentStorage<DynamicExtent>
|
|||||||
{
|
{
|
||||||
return extent;
|
return extent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr void setExtent(size_t extent)
|
||||||
|
{
|
||||||
|
this->extent = extent;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<size_t Extent>
|
template<size_t Extent>
|
||||||
@ -51,6 +59,8 @@ struct yExtent: extentStorage<Extent>
|
|||||||
template<typename T, size_t Width = DynamicExtent, size_t Height = DynamicExtent>
|
template<typename T, size_t Width = DynamicExtent, size_t Height = DynamicExtent>
|
||||||
class PlaneAdapter: xExtent<Width>, yExtent<Height>
|
class PlaneAdapter: xExtent<Width>, yExtent<Height>
|
||||||
{
|
{
|
||||||
|
friend class VideoBuffer; // TODO: remove
|
||||||
|
|
||||||
using value_type = std::remove_reference_t<decltype(std::declval<T>()[0])>;
|
using value_type = std::remove_reference_t<decltype(std::declval<T>()[0])>;
|
||||||
using iterator = decltype(std::begin(std::declval<T &>()));
|
using iterator = decltype(std::begin(std::declval<T &>()));
|
||||||
using const_iterator = decltype(std::begin(std::declval<T const &>()));
|
using const_iterator = decltype(std::begin(std::declval<T const &>()));
|
||||||
@ -78,9 +88,11 @@ public:
|
|||||||
|
|
||||||
PlaneAdapter(PlaneAdapter &&) = default;
|
PlaneAdapter(PlaneAdapter &&) = default;
|
||||||
|
|
||||||
PlaneAdapter &operator=(PlaneAdapter const &) = default;
|
PlaneAdapter(Vec2<int> size, T &&base):
|
||||||
|
xExtent<Width>(size.X),
|
||||||
PlaneAdapter &operator=(PlaneAdapter &&) = default;
|
yExtent<Height>(size.Y),
|
||||||
|
Base(std::move(base))
|
||||||
|
{}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
PlaneAdapter(Vec2<int> size, Args&&... args):
|
PlaneAdapter(Vec2<int> size, Args&&... args):
|
||||||
@ -89,11 +101,21 @@ public:
|
|||||||
Base(getWidth() * getHeight(), std::forward<Args>(args)...)
|
Base(getWidth() * getHeight(), std::forward<Args>(args)...)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
PlaneAdapter &operator=(PlaneAdapter const &) = default;
|
||||||
|
|
||||||
|
PlaneAdapter &operator=(PlaneAdapter &&) = default;
|
||||||
|
|
||||||
Vec2<int> Size() const
|
Vec2<int> Size() const
|
||||||
{
|
{
|
||||||
return Vec2<int>(getWidth(), getHeight());
|
return Vec2<int>(getWidth(), getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSize(Vec2<int> size)
|
||||||
|
{
|
||||||
|
xExtent<Width>::setExtent(size.X);
|
||||||
|
yExtent<Height>::setExtent(size.Y);
|
||||||
|
}
|
||||||
|
|
||||||
iterator RowIterator(Vec2<int> p)
|
iterator RowIterator(Vec2<int> p)
|
||||||
{
|
{
|
||||||
return std::begin(Base) + (p.X + p.Y * getWidth());
|
return std::begin(Base) + (p.X + p.Y * getWidth());
|
||||||
|
@ -1,60 +1,62 @@
|
|||||||
#include "Graphics.h"
|
#include <algorithm>
|
||||||
#include "common/platform/Platform.h"
|
#include <bzlib.h>
|
||||||
#include "FontReader.h"
|
|
||||||
#include "resampler/resampler.h"
|
|
||||||
#include "SimulationConfig.h"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <bzlib.h>
|
#include <iostream>
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
#include "common/platform/Platform.h"
|
||||||
|
#include "FontReader.h"
|
||||||
|
#include "Graphics.h"
|
||||||
|
#include "resampler/resampler.h"
|
||||||
|
#include "SimulationConfig.h"
|
||||||
|
|
||||||
|
VideoBuffer::VideoBuffer(Vec2<int> size):
|
||||||
|
video(size)
|
||||||
|
{}
|
||||||
|
|
||||||
|
VideoBuffer::VideoBuffer(pixel const *data, Vec2<int> size):
|
||||||
|
VideoBuffer(size)
|
||||||
|
{
|
||||||
|
std::copy_n(data, size.X * size.Y, video.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoBuffer::VideoBuffer(pixel const *data, Vec2<int> size, size_t rowStride):
|
||||||
|
VideoBuffer(size)
|
||||||
|
{
|
||||||
|
for(int y = 0; y < size.Y; y++)
|
||||||
|
std::copy_n(data + rowStride * y, size.X, video.RowIterator(Vec2(0, y)));
|
||||||
|
}
|
||||||
|
|
||||||
VideoBuffer::VideoBuffer(int width, int height):
|
VideoBuffer::VideoBuffer(int width, int height):
|
||||||
Width(width),
|
VideoBuffer(Vec2(width, height))
|
||||||
Height(height)
|
{}
|
||||||
{
|
|
||||||
Buffer = new pixel[width*height];
|
|
||||||
std::fill(Buffer, Buffer+(width*height), 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
VideoBuffer::VideoBuffer(const VideoBuffer & old):
|
|
||||||
Width(old.Width),
|
|
||||||
Height(old.Height)
|
|
||||||
{
|
|
||||||
Buffer = new pixel[old.Width*old.Height];
|
|
||||||
std::copy(old.Buffer, old.Buffer+(old.Width*old.Height), Buffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
VideoBuffer::VideoBuffer(VideoBuffer * old):
|
VideoBuffer::VideoBuffer(VideoBuffer * old):
|
||||||
Width(old->Width),
|
VideoBuffer(*old)
|
||||||
Height(old->Height)
|
{}
|
||||||
{
|
|
||||||
Buffer = new pixel[old->Width*old->Height];
|
|
||||||
std::copy(old->Buffer, old->Buffer+(old->Width*old->Height), Buffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
VideoBuffer::VideoBuffer(pixel * buffer, int width, int height, int pitch):
|
VideoBuffer::VideoBuffer(pixel const *buffer, int width, int height, int pitch):
|
||||||
Width(width),
|
VideoBuffer(buffer, Vec2(width, height), pitch == 0 ? width : pitch)
|
||||||
Height(height)
|
{}
|
||||||
{
|
|
||||||
Buffer = new pixel[width*height];
|
|
||||||
CopyData(buffer, width, height, pitch ? pitch : width);
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoBuffer::CopyData(pixel * buffer, int width, int height, int pitch)
|
void VideoBuffer::CopyData(pixel * buffer, int width, int height, int pitch)
|
||||||
{
|
{
|
||||||
for (auto y = 0; y < height; ++y)
|
for (auto y = 0; y < height; ++y)
|
||||||
{
|
{
|
||||||
std::copy(buffer + y * pitch, buffer + y * pitch + width, Buffer + y * width);
|
std::copy(buffer + y * pitch, buffer + y * pitch + width, Buffer.data() + y * width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VideoBuffer::Crop(Rect<int> rect)
|
||||||
|
{
|
||||||
|
Crop(rect.Size().X, rect.Size().Y, rect.TopLeft.X, rect.TopLeft.Y);
|
||||||
|
}
|
||||||
|
|
||||||
void VideoBuffer::Crop(int width, int height, int x, int y)
|
void VideoBuffer::Crop(int width, int height, int x, int y)
|
||||||
{
|
{
|
||||||
CopyData(Buffer + y * Width + x, width, height, Width);
|
CopyData(Buffer.data() + y * Width + x, width, height, Width);
|
||||||
Width = width;
|
video.SetSize(Vec2(width, height));
|
||||||
Height = height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBuffer::Resize(float factor, bool resample)
|
void VideoBuffer::Resize(float factor, bool resample)
|
||||||
@ -87,16 +89,15 @@ void VideoBuffer::Resize(int width, int height, bool resample, bool fixedRatio)
|
|||||||
newHeight = (int)(Height * (newWidth/(float)Width));
|
newHeight = (int)(Height * (newWidth/(float)Width));
|
||||||
}
|
}
|
||||||
if(resample)
|
if(resample)
|
||||||
newBuffer = Graphics::resample_img(Buffer, Width, Height, newWidth, newHeight);
|
newBuffer = Graphics::resample_img(Buffer.data(), Width, Height, newWidth, newHeight);
|
||||||
else
|
else
|
||||||
newBuffer = Graphics::resample_img_nn(Buffer, Width, Height, newWidth, newHeight);
|
newBuffer = Graphics::resample_img_nn(Buffer.data(), Width, Height, newWidth, newHeight);
|
||||||
|
|
||||||
if(newBuffer)
|
if(newBuffer)
|
||||||
{
|
{
|
||||||
delete[] Buffer;
|
Buffer.assign(newBuffer, newBuffer + newWidth * newHeight);
|
||||||
Buffer = newBuffer;
|
delete[] newBuffer;
|
||||||
Width = newWidth;
|
video.SetSize(Vec2(newWidth, newHeight));
|
||||||
Height = newHeight;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,11 +128,6 @@ int VideoBuffer::AddCharacter(int x, int y, String::value_type c, int r, int g,
|
|||||||
return x + reader.GetWidth();
|
return x + reader.GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoBuffer::~VideoBuffer()
|
|
||||||
{
|
|
||||||
delete[] Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel *Graphics::resample_img_nn(pixel * src, int sw, int sh, int rw, int rh)
|
pixel *Graphics::resample_img_nn(pixel * src, int sw, int sh, int rw, int rh)
|
||||||
{
|
{
|
||||||
int y, x;
|
int y, x;
|
||||||
@ -739,7 +735,7 @@ void Graphics::draw_rgba_image(const pixel *data, int w, int h, int x, int y, fl
|
|||||||
VideoBuffer Graphics::DumpFrame()
|
VideoBuffer Graphics::DumpFrame()
|
||||||
{
|
{
|
||||||
VideoBuffer newBuffer(WINDOWW, WINDOWH);
|
VideoBuffer newBuffer(WINDOWW, WINDOWH);
|
||||||
std::copy(vid, vid+(WINDOWW*WINDOWH), newBuffer.Buffer);
|
std::copy(vid, vid+(WINDOWW*WINDOWH), newBuffer.Buffer.data());
|
||||||
return newBuffer;
|
return newBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,66 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/Plane.h"
|
||||||
#include "common/String.h"
|
#include "common/String.h"
|
||||||
#include "common/tpt-inline.h"
|
#include "common/tpt-inline.h"
|
||||||
#include "Pixel.h"
|
|
||||||
#include "Icons.h"
|
#include "Icons.h"
|
||||||
|
#include "Pixel.h"
|
||||||
|
#include "RasterDrawMethods.h"
|
||||||
|
#include "SimulationConfig.h"
|
||||||
|
|
||||||
//"Graphics lite" - slightly lower performance due to variable size,
|
class VideoBuffer: public RasterDrawMethods<VideoBuffer>
|
||||||
class VideoBuffer
|
|
||||||
{
|
{
|
||||||
public:
|
PlaneAdapter<std::vector<pixel>> video;
|
||||||
pixel * Buffer;
|
|
||||||
int Width, Height;
|
Rect<int> getClipRect() const
|
||||||
|
{
|
||||||
|
return video.Size().OriginRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct RasterDrawMethods<VideoBuffer>;
|
||||||
|
|
||||||
|
void CopyData(pixel * buffer, int width, int height, int pitch);
|
||||||
|
|
||||||
|
public:
|
||||||
|
[[deprecated("Use video")]]
|
||||||
|
std::vector<pixel> &Buffer = video.Base;
|
||||||
|
[[deprecated("Use Size()")]]
|
||||||
|
size_t &Width = video.xExtent<DynamicExtent>::extent; // See TODO in common/Plane.h
|
||||||
|
[[deprecated("Use Size()")]]
|
||||||
|
size_t &Height = video.yExtent<DynamicExtent>::extent;
|
||||||
|
|
||||||
|
VideoBuffer(VideoBuffer const &) = default;
|
||||||
|
VideoBuffer(pixel const *data, Vec2<int> size);
|
||||||
|
VideoBuffer(pixel const *data, Vec2<int> size, size_t rowStride);
|
||||||
|
VideoBuffer(Vec2<int> size);
|
||||||
|
|
||||||
|
Vec2<int> Size() const
|
||||||
|
{
|
||||||
|
return video.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel const *Data() const
|
||||||
|
{
|
||||||
|
return video.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crop(Rect<int>);
|
||||||
|
|
||||||
VideoBuffer(const VideoBuffer & old);
|
|
||||||
VideoBuffer(VideoBuffer * old);
|
|
||||||
VideoBuffer(pixel * buffer, int width, int height, int pitch = 0);
|
|
||||||
VideoBuffer(int width, int height);
|
|
||||||
void Resize(float factor, bool resample = false);
|
void Resize(float factor, bool resample = false);
|
||||||
|
void Resize(Vec2<int> size, bool resamble = false, bool fixedRatio = true);
|
||||||
|
|
||||||
|
[[deprecated("Use VideoBuffer(VideoBuffer const &)")]]
|
||||||
|
VideoBuffer(VideoBuffer * old);
|
||||||
|
[[deprecated("Use VideoBuffer(pixel const *, Vec2<int>)")]]
|
||||||
|
VideoBuffer(pixel const *buffer, int width, int height, int pitch = 0);
|
||||||
|
[[deprecated("Use VideoBuffer(Vec2<int>)")]]
|
||||||
|
VideoBuffer(int width, int height);
|
||||||
|
[[deprecated("Use Resize(Vec2<int>, bool, bool)")]]
|
||||||
void Resize(int width, int height, bool resample = false, bool fixedRatio = true);
|
void Resize(int width, int height, bool resample = false, bool fixedRatio = true);
|
||||||
|
[[deprecated("Use Crop(Rect<int>)")]]
|
||||||
void Crop(int width, int height, int x, int y);
|
void Crop(int width, int height, int x, int y);
|
||||||
|
|
||||||
TPT_INLINE void BlendPixel(int x, int y, int r, int g, int b, int a)
|
TPT_INLINE void BlendPixel(int x, int y, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
pixel t;
|
pixel t;
|
||||||
@ -60,22 +103,39 @@ public:
|
|||||||
int SetCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
int SetCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
||||||
int BlendCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
int BlendCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
||||||
int AddCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
int AddCharacter(int x, int y, String::value_type c, int r, int g, int b, int a);
|
||||||
~VideoBuffer();
|
|
||||||
|
|
||||||
void CopyData(pixel * buffer, int width, int height, int pitch);
|
|
||||||
bool WritePNG(const ByteString &path) const;
|
bool WritePNG(const ByteString &path) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Graphics
|
class Graphics: public RasterDrawMethods<Graphics>
|
||||||
{
|
{
|
||||||
int clipx1;
|
PlaneAdapter<std::array<pixel, WINDOW.X * WINDOW.Y>, WINDOW.X, WINDOW.Y> video;
|
||||||
int clipy1;
|
Rect<int> clipRect = video.Size().OriginRect();
|
||||||
int clipx2;
|
|
||||||
int clipy2;
|
Rect<int> getClipRect() const
|
||||||
|
{
|
||||||
|
return clipRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct RasterDrawMethods<Graphics>;
|
||||||
|
|
||||||
|
[[deprecated("Use clipRect")]]
|
||||||
|
int &clipx1 = clipRect.TopLeft.X;
|
||||||
|
[[deprecated("Use clipRect")]]
|
||||||
|
int &clipy1 = clipRect.TopLeft.Y;
|
||||||
|
[[deprecated("Use clipRect")]]
|
||||||
|
int &clipx2 = clipRect.BottomRight.X;
|
||||||
|
[[deprecated("Use clipRect")]]
|
||||||
|
int &clipy2 = clipRect.BottomRight.Y;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pixel *vid;
|
pixel const *Data() const
|
||||||
int sdl_scale;
|
{
|
||||||
|
return video.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[deprecated("Use Data()")]]
|
||||||
|
pixel *vid = video.data();
|
||||||
|
|
||||||
struct GradientStop
|
struct GradientStop
|
||||||
{
|
{
|
||||||
@ -98,38 +158,15 @@ public:
|
|||||||
|
|
||||||
VideoBuffer DumpFrame();
|
VideoBuffer DumpFrame();
|
||||||
|
|
||||||
void blendpixel(int x, int y, int r, int g, int b, int a);
|
|
||||||
void addpixel(int x, int y, int r, int g, int b, int a);
|
|
||||||
|
|
||||||
void draw_icon(int x, int y, Icon icon, unsigned char alpha = 255, bool invert = false);
|
void draw_icon(int x, int y, Icon icon, unsigned char alpha = 255, bool invert = false);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
void Finalise();
|
void Finalise();
|
||||||
//
|
|
||||||
int drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a);
|
|
||||||
int drawtext(int x, int y, const String &s, int r, int g, int b, int a);
|
|
||||||
int drawchar(int x, int y, String::value_type c, int r, int g, int b, int a);
|
|
||||||
int addchar(int x, int y, String::value_type c, int r, int g, int b, int a);
|
|
||||||
|
|
||||||
void xor_pixel(int x, int y);
|
|
||||||
void xor_line(int x, int y, int x2, int y2);
|
|
||||||
void xor_rect(int x, int y, int width, int height);
|
|
||||||
void xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h);
|
|
||||||
|
|
||||||
void draw_line(int x, int y, int x2, int y2, int r, int g, int b, int a);
|
|
||||||
void drawrect(int x, int y, int width, int height, int r, int g, int b, int a);
|
|
||||||
void fillrect(int x, int y, int width, int height, int r, int g, int b, int a);
|
|
||||||
void drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
|
||||||
void fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
|
||||||
void clearrect(int x, int y, int width, int height);
|
|
||||||
void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2);
|
|
||||||
|
|
||||||
void draw_image(const pixel *img, int x, int y, int w, int h, int a);
|
|
||||||
void draw_image(const VideoBuffer * vidBuf, int x, int y, int a);
|
|
||||||
void draw_rgba_image(const pixel *data, int w, int h, int x, int y, float alpha);
|
void draw_rgba_image(const pixel *data, int w, int h, int x, int y, float alpha);
|
||||||
|
|
||||||
Graphics();
|
Graphics()
|
||||||
~Graphics();
|
{}
|
||||||
|
|
||||||
void SetClipRect(int &x, int &y, int &w, int &h);
|
void SetClipRect(int &x, int &y, int &w, int &h);
|
||||||
};
|
};
|
||||||
|
32
src/graphics/RasterDrawMethods.h
Normal file
32
src/graphics/RasterDrawMethods.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common/String.h"
|
||||||
|
#include "common/Vec2.h"
|
||||||
|
#include "graphics/Pixel.h"
|
||||||
|
|
||||||
|
class VideoBuffer;
|
||||||
|
|
||||||
|
// This is a mixin that adds methods to the Derived class, using the "Curiously
|
||||||
|
// Recurring Template Pattern" trick.
|
||||||
|
template<typename Derived>
|
||||||
|
struct RasterDrawMethods
|
||||||
|
{
|
||||||
|
int drawtext_outline(int x, int y, const String &, int r, int g, int b, int a);
|
||||||
|
int drawtext(int x, int y, const String &, int r, int g, int b, int a);
|
||||||
|
int drawchar(int x, int y, String::value_type, int r, int g, int b, int a);
|
||||||
|
int addchar(int x, int y, String::value_type, int r, int g, int b, int a);
|
||||||
|
void xor_pixel(int x, int y);
|
||||||
|
void blendpixel(int x, int y, int r, int g, int b, int a);
|
||||||
|
void addpixel(int x, int y, int r, int g, int b, int a);
|
||||||
|
void xor_line(int x1, int y1, int x2, int y2);
|
||||||
|
void xor_rect(int x, int y, int w, int h);
|
||||||
|
void xor_bitmap(unsigned char *bitmap, int x, int y, int w, int h);
|
||||||
|
void draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a);
|
||||||
|
void drawrect(int x, int y, int w, int h, int r, int g, int b, int a);
|
||||||
|
void fillrect(int x, int y, int w, int h, int r, int g, int b, int a);
|
||||||
|
void drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
||||||
|
void fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
||||||
|
void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2);
|
||||||
|
void clearrect(int x, int y, int w, int h);
|
||||||
|
void draw_image(pixel const *, int x, int y, int w, int h, int a);
|
||||||
|
void draw_image(VideoBuffer const *, int x, int y, int a);
|
||||||
|
};
|
@ -1,7 +1,16 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
#include "RasterDrawMethods.h"
|
||||||
|
#include "Graphics.h"
|
||||||
#include "FontReader.h"
|
#include "FontReader.h"
|
||||||
|
|
||||||
int PIXELMETHODS_CLASS::drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a)
|
#define vid() (static_cast<Derived &>(*this).video.RowIterator(Vec2(0, 0)))
|
||||||
|
#define clipRect() (static_cast<Derived const &>(*this).getClipRect())
|
||||||
|
#define VIDXRES (static_cast<Derived const &>(*this).video.Size().X)
|
||||||
|
#define VIDYRES (static_cast<Derived const &>(*this).video.Size().Y)
|
||||||
|
|
||||||
|
template<typename Derived>
|
||||||
|
int RasterDrawMethods<Derived>::drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
drawtext(x-1, y-1, s, 0, 0, 0, 120);
|
drawtext(x-1, y-1, s, 0, 0, 0, 120);
|
||||||
drawtext(x+1, y+1, s, 0, 0, 0, 120);
|
drawtext(x+1, y+1, s, 0, 0, 0, 120);
|
||||||
@ -12,7 +21,8 @@ int PIXELMETHODS_CLASS::drawtext_outline(int x, int y, const String &s, int r, i
|
|||||||
return drawtext(x, y, s, r, g, b, a);
|
return drawtext(x, y, s, r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PIXELMETHODS_CLASS::drawtext(int x, int y, const String &str, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
int RasterDrawMethods<Derived>::drawtext(int x, int y, const String &str, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
if(!str.size())
|
if(!str.size())
|
||||||
return 0;
|
return 0;
|
||||||
@ -95,7 +105,8 @@ int PIXELMETHODS_CLASS::drawtext(int x, int y, const String &str, int r, int g,
|
|||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PIXELMETHODS_CLASS::drawchar(int x, int y, String::value_type c, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
int RasterDrawMethods<Derived>::drawchar(int x, int y, String::value_type c, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
FontReader reader(c);
|
FontReader reader(c);
|
||||||
for (int j = -2; j < FONT_H - 2; j++)
|
for (int j = -2; j < FONT_H - 2; j++)
|
||||||
@ -104,7 +115,8 @@ int PIXELMETHODS_CLASS::drawchar(int x, int y, String::value_type c, int r, int
|
|||||||
return x + reader.GetWidth();
|
return x + reader.GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PIXELMETHODS_CLASS::addchar(int x, int y, String::value_type c, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
int RasterDrawMethods<Derived>::addchar(int x, int y, String::value_type c, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
FontReader reader(c);
|
FontReader reader(c);
|
||||||
for (int j = -2; j < FONT_H - 2; j++)
|
for (int j = -2; j < FONT_H - 2; j++)
|
||||||
@ -113,52 +125,43 @@ int PIXELMETHODS_CLASS::addchar(int x, int y, String::value_type c, int r, int g
|
|||||||
return x + reader.GetWidth();
|
return x + reader.GetWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
TPT_INLINE void PIXELMETHODS_CLASS::xor_pixel(int x, int y)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::xor_pixel(int x, int y)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
#ifdef DO_CLIPCHECK
|
if (!clipRect().Contains(Vec2(x, y)))
|
||||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
|
||||||
#else
|
|
||||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
c = vid[y*(VIDXRES)+x];
|
c = vid()[y*(VIDXRES)+x];
|
||||||
c = PIXB(c) + 3*PIXG(c) + 2*PIXR(c);
|
c = PIXB(c) + 3*PIXG(c) + 2*PIXR(c);
|
||||||
if (c<512)
|
if (c<512)
|
||||||
vid[y*(VIDXRES)+x] = PIXPACK(0xC0C0C0);
|
vid()[y*(VIDXRES)+x] = PIXPACK(0xC0C0C0);
|
||||||
else
|
else
|
||||||
vid[y*(VIDXRES)+x] = PIXPACK(0x404040);
|
vid()[y*(VIDXRES)+x] = PIXPACK(0x404040);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::blendpixel(int x, int y, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::blendpixel(int x, int y, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
pixel t;
|
pixel t;
|
||||||
#ifdef DO_CLIPCHECK
|
if (!clipRect().Contains(Vec2(x, y)))
|
||||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
|
||||||
#else
|
|
||||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
if (a!=255)
|
if (a!=255)
|
||||||
{
|
{
|
||||||
t = vid[y*(VIDXRES)+x];
|
t = vid()[y*(VIDXRES)+x];
|
||||||
r = (a*r + (255-a)*PIXR(t)) >> 8;
|
r = (a*r + (255-a)*PIXR(t)) >> 8;
|
||||||
g = (a*g + (255-a)*PIXG(t)) >> 8;
|
g = (a*g + (255-a)*PIXG(t)) >> 8;
|
||||||
b = (a*b + (255-a)*PIXB(t)) >> 8;
|
b = (a*b + (255-a)*PIXB(t)) >> 8;
|
||||||
}
|
}
|
||||||
vid[y*(VIDXRES)+x] = PIXRGB(r,g,b);
|
vid()[y*(VIDXRES)+x] = PIXRGB(r,g,b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::addpixel(int x, int y, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::addpixel(int x, int y, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
pixel t;
|
pixel t;
|
||||||
#ifdef DO_CLIPCHECK
|
if (!clipRect().Contains(Vec2(x, y)))
|
||||||
if (x<clipx1 || y<clipy1 || x>=clipx2 || y>=clipy2)
|
|
||||||
#else
|
|
||||||
if (x<0 || y<0 || x>=VIDXRES || y>=VIDYRES)
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
t = vid[y*(VIDXRES)+x];
|
t = vid()[y*(VIDXRES)+x];
|
||||||
r = (a*r + 255*PIXR(t)) >> 8;
|
r = (a*r + 255*PIXR(t)) >> 8;
|
||||||
g = (a*g + 255*PIXG(t)) >> 8;
|
g = (a*g + 255*PIXG(t)) >> 8;
|
||||||
b = (a*b + 255*PIXB(t)) >> 8;
|
b = (a*b + 255*PIXB(t)) >> 8;
|
||||||
@ -168,10 +171,11 @@ void PIXELMETHODS_CLASS::addpixel(int x, int y, int r, int g, int b, int a)
|
|||||||
g = 255;
|
g = 255;
|
||||||
if (b>255)
|
if (b>255)
|
||||||
b = 255;
|
b = 255;
|
||||||
vid[y*(VIDXRES)+x] = PIXRGB(r,g,b);
|
vid()[y*(VIDXRES)+x] = PIXRGB(r,g,b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::xor_line(int x1, int y1, int x2, int y2)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::xor_line(int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
||||||
float e, de;
|
float e, de;
|
||||||
@ -217,7 +221,8 @@ void PIXELMETHODS_CLASS::xor_line(int x1, int y1, int x2, int y2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::xor_rect(int x, int y, int w, int h)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::xor_rect(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<w; i+=2)
|
for (i=0; i<w; i+=2)
|
||||||
@ -249,7 +254,8 @@ void PIXELMETHODS_CLASS::xor_rect(int x, int y, int w, int h)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
for(int x1 = 0; x1 < w; x1++)
|
for(int x1 = 0; x1 < w; x1++)
|
||||||
{
|
{
|
||||||
@ -261,7 +267,8 @@ void PIXELMETHODS_CLASS::xor_bitmap(unsigned char * bitmap, int x, int y, int w,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::draw_line(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
int cp=abs(y2-y1)>abs(x2-x1), x, y, dx, dy, sy;
|
||||||
float e, de;
|
float e, de;
|
||||||
@ -307,7 +314,8 @@ void PIXELMETHODS_CLASS::draw_line(int x1, int y1, int x2, int y2, int r, int g,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::drawrect(int x, int y, int w, int h, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::drawrect(int x, int y, int w, int h, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
w--;
|
w--;
|
||||||
@ -324,7 +332,8 @@ void PIXELMETHODS_CLASS::drawrect(int x, int y, int w, int h, int r, int g, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::fillrect(int x, int y, int w, int h, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::fillrect(int x, int y, int w, int h, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
for (j=0; j<h; j++)
|
for (j=0; j<h; j++)
|
||||||
@ -332,7 +341,8 @@ void PIXELMETHODS_CLASS::fillrect(int x, int y, int w, int h, int r, int g, int
|
|||||||
blendpixel(x+i, y+j, r, g, b, a);
|
blendpixel(x+i, y+j, r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
int yTop = ry, yBottom, i, j;
|
int yTop = ry, yBottom, i, j;
|
||||||
if (!rx)
|
if (!rx)
|
||||||
@ -362,7 +372,8 @@ void PIXELMETHODS_CLASS::drawcircle(int x, int y, int rx, int ry, int r, int g,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a)
|
||||||
{
|
{
|
||||||
int yTop = ry+1, yBottom, i, j;
|
int yTop = ry+1, yBottom, i, j;
|
||||||
if (!rx)
|
if (!rx)
|
||||||
@ -385,12 +396,14 @@ void PIXELMETHODS_CLASS::fillcircle(int x, int y, int rx, int ry, int r, int g,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::clearrect(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -400,41 +413,21 @@ void PIXELMETHODS_CLASS::clearrect(int x, int y, int w, int h)
|
|||||||
w -= 1;
|
w -= 1;
|
||||||
h -= 1;
|
h -= 1;
|
||||||
|
|
||||||
#ifdef DO_CLIPCHECK
|
Rect rect = clipRect() & RectSized(Vec2(x, y), Vec2(w, h));
|
||||||
if (x+w > clipx2) w = clipx2-x;
|
x = rect.TopLeft.X;
|
||||||
if (y+h > clipy2) h = clipy2-y;
|
y = rect.TopLeft.Y;
|
||||||
if (x<clipx1)
|
w = rect.Size().X;
|
||||||
{
|
h = rect.Size().Y;
|
||||||
w += x - clipx1;
|
|
||||||
x = clipx1;
|
|
||||||
}
|
|
||||||
if (y<clipy1)
|
|
||||||
{
|
|
||||||
h += y - clipy1;
|
|
||||||
y = clipy1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (x+w > VIDXRES) w = VIDXRES-x;
|
|
||||||
if (y+h > VIDYRES) h = VIDYRES-y;
|
|
||||||
if (x<0)
|
|
||||||
{
|
|
||||||
w += x;
|
|
||||||
x = 0;
|
|
||||||
}
|
|
||||||
if (y<0)
|
|
||||||
{
|
|
||||||
h += y;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (w<0 || h<0)
|
if (w<0 || h<0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i=0; i<h; i++)
|
for (i=0; i<h; i++)
|
||||||
memset(vid+(x+(VIDXRES)*(y+i)), 0, PIXELSIZE*w);
|
memset(vid()+(x+(VIDXRES)*(y+i)), 0, PIXELSIZE*w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::draw_image(const pixel *img, int x, int y, int w, int h, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::draw_image(const pixel *img, int x, int y, int w, int h, int a)
|
||||||
{
|
{
|
||||||
int startX = 0;
|
int startX = 0;
|
||||||
if (!img)
|
if (!img)
|
||||||
@ -467,10 +460,8 @@ void PIXELMETHODS_CLASS::draw_image(const pixel *img, int x, int y, int w, int h
|
|||||||
img += startX;
|
img += startX;
|
||||||
for (int i = startX; i < w; i++)
|
for (int i = startX; i < w; i++)
|
||||||
{
|
{
|
||||||
#ifdef DO_CLIPCHECK
|
if (clipRect().Contains(Vec2(x + i, y + j)))
|
||||||
if (!(x+i<clipx1 || y+j<clipy1 || x+i>=clipx2 || y+j>=clipy2))
|
vid()[(y+j)*(VIDXRES)+(x+i)] = *img;
|
||||||
#endif
|
|
||||||
vid[(y+j)*(VIDXRES)+(x+i)] = *img;
|
|
||||||
img++;
|
img++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -492,7 +483,8 @@ void PIXELMETHODS_CLASS::draw_image(const pixel *img, int x, int y, int w, int h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIXELMETHODS_CLASS::draw_image(const VideoBuffer * vidBuf, int x, int y, int a)
|
template<typename Derived>
|
||||||
|
void RasterDrawMethods<Derived>::draw_image(const VideoBuffer * vidBuf, int x, int y, int a)
|
||||||
{
|
{
|
||||||
draw_image(vidBuf->Buffer, x, y, vidBuf->Width, vidBuf->Height, a);
|
draw_image(vidBuf->Buffer.data(), x, y, vidBuf->Width, vidBuf->Height, a);
|
||||||
}
|
}
|
@ -1,23 +1,8 @@
|
|||||||
#include "Graphics.h"
|
|
||||||
#include "SimulationConfig.h"
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include "Graphics.h"
|
||||||
Graphics::Graphics():
|
#include "SimulationConfig.h"
|
||||||
clipx1(0),
|
#include "RasterDrawMethodsImpl.h"
|
||||||
clipy1(0),
|
|
||||||
clipx2(WINDOWW),
|
|
||||||
clipy2(WINDOWH),
|
|
||||||
sdl_scale(1)
|
|
||||||
{
|
|
||||||
vid = (pixel *)malloc(PIXELSIZE * (WINDOWW * WINDOWH));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Graphics::~Graphics()
|
|
||||||
{
|
|
||||||
free(vid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::Clear()
|
void Graphics::Clear()
|
||||||
{
|
{
|
||||||
@ -29,9 +14,4 @@ void Graphics::Finalise()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr auto VIDXRES = WINDOWW;
|
template class RasterDrawMethods<Graphics>;
|
||||||
constexpr auto VIDYRES = WINDOWH;
|
|
||||||
#define PIXELMETHODS_CLASS Graphics
|
|
||||||
#define DO_CLIPCHECK
|
|
||||||
#include "RasterDrawMethods.inl"
|
|
||||||
#undef PIXELMETHODS_CLASS
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "gui/interface/Point.h"
|
#include "gui/interface/Point.h"
|
||||||
#include "SimulationConfig.h"
|
#include "SimulationConfig.h"
|
||||||
#include <vector>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
class RenderPreset;
|
class RenderPreset;
|
||||||
class Simulation;
|
class Simulation;
|
||||||
@ -32,11 +33,26 @@ typedef struct gcache_item gcache_item;
|
|||||||
|
|
||||||
int HeatToColour(float temp);
|
int HeatToColour(float temp);
|
||||||
|
|
||||||
class Renderer
|
class Renderer: public RasterDrawMethods<Renderer>
|
||||||
{
|
{
|
||||||
|
PlaneAdapter<std::array<pixel, WINDOW.X * RES.Y>, WINDOW.X, RES.Y> video;
|
||||||
|
std::array<pixel, WINDOW.X * RES.Y> persistentVideo;
|
||||||
|
PlaneAdapter<std::array<pixel, WINDOW.X * RES.Y>, WINDOW.X, RES.Y> warpVideo;
|
||||||
|
|
||||||
|
Rect<int> getClipRect() const
|
||||||
|
{
|
||||||
|
return video.Size().OriginRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct RasterDrawMethods<Renderer>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
pixel const *Data() const
|
||||||
|
{
|
||||||
|
return video.data();
|
||||||
|
}
|
||||||
|
|
||||||
Simulation * sim;
|
Simulation * sim;
|
||||||
Graphics * g;
|
|
||||||
gcache_item *graphicscache;
|
gcache_item *graphicscache;
|
||||||
|
|
||||||
std::vector<unsigned int> render_modes;
|
std::vector<unsigned int> render_modes;
|
||||||
@ -89,38 +105,18 @@ public:
|
|||||||
void FinaliseParts();
|
void FinaliseParts();
|
||||||
|
|
||||||
void ClearAccumulation();
|
void ClearAccumulation();
|
||||||
void clearScreen(float alpha);
|
void clearScreen();
|
||||||
void SetSample(int x, int y);
|
void SetSample(int x, int y);
|
||||||
|
|
||||||
pixel * vid;
|
[[deprecated("Use video")]]
|
||||||
pixel * persistentVid;
|
pixel *const vid = video.Base.data();
|
||||||
pixel * warpVid;
|
[[deprecated("Use persistentVideo")]]
|
||||||
void blendpixel(int x, int y, int r, int g, int b, int a);
|
pixel *const persistentVid = persistentVideo.data();
|
||||||
void addpixel(int x, int y, int r, int g, int b, int a);
|
[[deprecated("Use wrapVideo")]]
|
||||||
|
pixel *const warpVid = warpVideo.data();
|
||||||
|
|
||||||
void draw_icon(int x, int y, Icon icon);
|
void draw_icon(int x, int y, Icon icon);
|
||||||
|
|
||||||
int drawtext_outline(int x, int y, const String &s, int r, int g, int b, int a);
|
|
||||||
int drawtext(int x, int y, const String &s, int r, int g, int b, int a);
|
|
||||||
int drawchar(int x, int y, String::value_type c, int r, int g, int b, int a);
|
|
||||||
int addchar(int x, int y, String::value_type c, int r, int g, int b, int a);
|
|
||||||
|
|
||||||
void xor_pixel(int x, int y);
|
|
||||||
void xor_line(int x, int y, int x2, int y2);
|
|
||||||
void xor_rect(int x, int y, int width, int height);
|
|
||||||
void xor_bitmap(unsigned char * bitmap, int x, int y, int w, int h);
|
|
||||||
|
|
||||||
void draw_line(int x, int y, int x2, int y2, int r, int g, int b, int a);
|
|
||||||
void drawrect(int x, int y, int width, int height, int r, int g, int b, int a);
|
|
||||||
void fillrect(int x, int y, int width, int height, int r, int g, int b, int a);
|
|
||||||
void drawcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
|
||||||
void fillcircle(int x, int y, int rx, int ry, int r, int g, int b, int a);
|
|
||||||
void clearrect(int x, int y, int width, int height);
|
|
||||||
void gradientrect(int x, int y, int width, int height, int r, int g, int b, int a, int r2, int g2, int b2, int a2);
|
|
||||||
|
|
||||||
void draw_image(const pixel *img, int x, int y, int w, int h, int a);
|
|
||||||
void draw_image(const VideoBuffer * vidBuf, int w, int h, int a);
|
|
||||||
|
|
||||||
VideoBuffer DumpFrame();
|
VideoBuffer DumpFrame();
|
||||||
|
|
||||||
void drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb);
|
void drawblob(int x, int y, unsigned char cr, unsigned char cg, unsigned char cb);
|
||||||
@ -148,7 +144,7 @@ public:
|
|||||||
|
|
||||||
static VideoBuffer * WallIcon(int wallID, int width, int height);
|
static VideoBuffer * WallIcon(int wallID, int width, int height);
|
||||||
|
|
||||||
Renderer(Graphics * g, Simulation * sim);
|
Renderer(Simulation * sim);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
#define RENDERER_TABLE(name) \
|
#define RENDERER_TABLE(name) \
|
||||||
|
@ -1,27 +1,19 @@
|
|||||||
#include "Renderer.h"
|
|
||||||
#include "gui/game/RenderPreset.h"
|
|
||||||
#include "simulation/Simulation.h"
|
|
||||||
#include "simulation/ElementGraphics.h"
|
|
||||||
#include "simulation/ElementClasses.h"
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include "gui/game/RenderPreset.h"
|
||||||
|
#include "RasterDrawMethodsImpl.h"
|
||||||
|
#include "Renderer.h"
|
||||||
|
#include "simulation/ElementClasses.h"
|
||||||
|
#include "simulation/ElementGraphics.h"
|
||||||
|
#include "simulation/Simulation.h"
|
||||||
|
|
||||||
|
#undef VIDXRES
|
||||||
|
#undef VIDYRES
|
||||||
|
|
||||||
constexpr auto VIDXRES = WINDOWW;
|
constexpr auto VIDXRES = WINDOWW;
|
||||||
constexpr auto VIDYRES = WINDOWH;
|
constexpr auto VIDYRES = WINDOWH;
|
||||||
|
|
||||||
void Renderer::RenderBegin()
|
void Renderer::RenderBegin()
|
||||||
{
|
{
|
||||||
if(display_mode & DISPLAY_PERS)
|
|
||||||
{
|
|
||||||
std::copy(persistentVid, persistentVid+(VIDXRES*YRES), vid);
|
|
||||||
}
|
|
||||||
pixel * oldVid = NULL;
|
|
||||||
if(display_mode & DISPLAY_WARP)
|
|
||||||
{
|
|
||||||
oldVid = vid;
|
|
||||||
vid = warpVid;
|
|
||||||
std::fill(warpVid, warpVid+(VIDXRES*VIDYRES), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
draw_air();
|
draw_air();
|
||||||
draw_grav();
|
draw_grav();
|
||||||
DrawWalls();
|
DrawWalls();
|
||||||
@ -50,11 +42,6 @@ void Renderer::RenderBegin()
|
|||||||
draw_grav_zones();
|
draw_grav_zones();
|
||||||
DrawSigns();
|
DrawSigns();
|
||||||
|
|
||||||
if(display_mode & DISPLAY_WARP)
|
|
||||||
{
|
|
||||||
vid = oldVid;
|
|
||||||
}
|
|
||||||
|
|
||||||
FinaliseParts();
|
FinaliseParts();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,15 +55,24 @@ void Renderer::SetSample(int x, int y)
|
|||||||
sampleColor = GetPixel(x, y);
|
sampleColor = GetPixel(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::clearScreen(float alpha)
|
void Renderer::clearScreen()
|
||||||
{
|
{
|
||||||
g->Clear();
|
if(display_mode & DISPLAY_PERS)
|
||||||
|
{
|
||||||
|
std::copy(persistentVid, persistentVid+(VIDXRES*YRES), vid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::fill_n(video.data(), VIDXRES * YRES, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::FinaliseParts()
|
void Renderer::FinaliseParts()
|
||||||
{
|
{
|
||||||
if(display_mode & DISPLAY_WARP)
|
if(display_mode & DISPLAY_WARP)
|
||||||
{
|
{
|
||||||
|
warpVideo = video;
|
||||||
|
std::fill_n(video.data(), VIDXRES * YRES, 0);
|
||||||
render_gravlensing(warpVid);
|
render_gravlensing(warpVid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,9 +265,8 @@ void Renderer::PopulateTables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Renderer(Graphics * g, Simulation * sim):
|
Renderer::Renderer(Simulation * sim):
|
||||||
sim(NULL),
|
sim(NULL),
|
||||||
g(NULL),
|
|
||||||
render_mode(0),
|
render_mode(0),
|
||||||
colour_mode(0),
|
colour_mode(0),
|
||||||
display_mode(0),
|
display_mode(0),
|
||||||
@ -293,11 +288,7 @@ Renderer::Renderer(Graphics * g, Simulation * sim):
|
|||||||
{
|
{
|
||||||
PopulateTables();
|
PopulateTables();
|
||||||
|
|
||||||
this->g = g;
|
|
||||||
this->sim = sim;
|
this->sim = sim;
|
||||||
vid = g->vid;
|
|
||||||
persistentVid = new pixel[VIDXRES*YRES];
|
|
||||||
warpVid = new pixel[VIDXRES*VIDYRES];
|
|
||||||
|
|
||||||
memset(fire_r, 0, sizeof(fire_r));
|
memset(fire_r, 0, sizeof(fire_r));
|
||||||
memset(fire_g, 0, sizeof(fire_g));
|
memset(fire_g, 0, sizeof(fire_g));
|
||||||
@ -515,18 +506,14 @@ VideoBuffer Renderer::DumpFrame()
|
|||||||
VideoBuffer newBuffer(XRES, YRES);
|
VideoBuffer newBuffer(XRES, YRES);
|
||||||
for(int y = 0; y < YRES; y++)
|
for(int y = 0; y < YRES; y++)
|
||||||
{
|
{
|
||||||
std::copy(vid+(y*WINDOWW), vid+(y*WINDOWW)+XRES, newBuffer.Buffer+(y*XRES));
|
std::copy(vid+(y*WINDOWW), vid+(y*WINDOWW)+XRES, newBuffer.Buffer.data()+(y*XRES));
|
||||||
}
|
}
|
||||||
return newBuffer;
|
return newBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::~Renderer()
|
Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
delete[] persistentVid;
|
|
||||||
delete[] warpVid;
|
|
||||||
delete[] graphicscache;
|
delete[] graphicscache;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PIXELMETHODS_CLASS Renderer
|
template class RasterDrawMethods<Renderer>;
|
||||||
#include "RasterDrawMethods.inl"
|
|
||||||
#undef PIXELMETHODS_CLASS
|
|
||||||
|
@ -58,7 +58,7 @@ GameModel::GameModel():
|
|||||||
decoSpace(0)
|
decoSpace(0)
|
||||||
{
|
{
|
||||||
sim = new Simulation();
|
sim = new Simulation();
|
||||||
ren = new Renderer(ui::Engine::Ref().g, sim);
|
ren = new Renderer(sim);
|
||||||
|
|
||||||
activeTools = regularToolset;
|
activeTools = regularToolset;
|
||||||
|
|
||||||
|
@ -958,7 +958,7 @@ ByteString GameView::TakeScreenshot(int captureUI, int fileType)
|
|||||||
// We should be able to simply use SDL_PIXELFORMAT_XRGB8888 here with a bit depth of 32 to convert RGBA data to RGB data,
|
// We should be able to simply use SDL_PIXELFORMAT_XRGB8888 here with a bit depth of 32 to convert RGBA data to RGB data,
|
||||||
// and save the resulting surface directly. However, ubuntu-18.04 ships SDL2 so old that it doesn't have
|
// and save the resulting surface directly. However, ubuntu-18.04 ships SDL2 so old that it doesn't have
|
||||||
// SDL_PIXELFORMAT_XRGB8888, so we first create an RGBA surface and then convert it.
|
// SDL_PIXELFORMAT_XRGB8888, so we first create an RGBA surface and then convert it.
|
||||||
auto *rgbaSurface = SDL_CreateRGBSurfaceWithFormatFrom(screenshot->Buffer, screenshot->Width, screenshot->Height, 32, screenshot->Width * sizeof(pixel), SDL_PIXELFORMAT_ARGB8888);
|
auto *rgbaSurface = SDL_CreateRGBSurfaceWithFormatFrom(screenshot->Buffer.data(), screenshot->Width, screenshot->Height, 32, screenshot->Width * sizeof(pixel), SDL_PIXELFORMAT_ARGB8888);
|
||||||
auto *rgbSurface = SDL_ConvertSurfaceFormat(rgbaSurface, SDL_PIXELFORMAT_RGB888, 0);
|
auto *rgbSurface = SDL_ConvertSurfaceFormat(rgbaSurface, SDL_PIXELFORMAT_RGB888, 0);
|
||||||
if (!rgbSurface || SDL_SaveBMP(rgbSurface, filename.c_str()))
|
if (!rgbSurface || SDL_SaveBMP(rgbSurface, filename.c_str()))
|
||||||
{
|
{
|
||||||
@ -2074,7 +2074,7 @@ void GameView::OnDraw()
|
|||||||
Graphics * g = GetGraphics();
|
Graphics * g = GetGraphics();
|
||||||
if (ren)
|
if (ren)
|
||||||
{
|
{
|
||||||
ren->clearScreen(1.0f);
|
ren->clearScreen();
|
||||||
ren->RenderBegin();
|
ren->RenderBegin();
|
||||||
ren->SetSample(c->PointTranslate(currentMouse).X, c->PointTranslate(currentMouse).Y);
|
ren->SetSample(c->PointTranslate(currentMouse).X, c->PointTranslate(currentMouse).Y);
|
||||||
if (showBrush && selectMode == SelectNone && (!zoomEnabled || zoomCursorFixed) && activeBrush && (isMouseDown || (currentMouse.X >= 0 && currentMouse.X < XRES && currentMouse.Y >= 0 && currentMouse.Y < YRES)))
|
if (showBrush && selectMode == SelectNone && (!zoomEnabled || zoomCursorFixed) && activeBrush && (isMouseDown || (currentMouse.X >= 0 && currentMouse.X < XRES && currentMouse.Y >= 0 && currentMouse.Y < YRES)))
|
||||||
@ -2196,6 +2196,9 @@ void GameView::OnDraw()
|
|||||||
|
|
||||||
ren->RenderEnd();
|
ren->RenderEnd();
|
||||||
|
|
||||||
|
std::copy_n(ren->Data(), WINDOWW * YRES, g->vid);
|
||||||
|
|
||||||
|
|
||||||
if (doScreenshot)
|
if (doScreenshot)
|
||||||
{
|
{
|
||||||
doScreenshot = false;
|
doScreenshot = false;
|
||||||
|
@ -285,7 +285,7 @@ void PreviewView::OnDraw()
|
|||||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
|
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
|
||||||
|
|
||||||
//Save preview (top-left)
|
//Save preview (top-left)
|
||||||
if(savePreview && savePreview->Buffer)
|
if(savePreview)
|
||||||
{
|
{
|
||||||
g->draw_image(savePreview, (Position.X+1)+(((XRES/2)-savePreview->Width)/2), (Position.Y+1)+(((YRES/2)-savePreview->Height)/2), 255);
|
g->draw_image(savePreview, (Position.X+1)+(((XRES/2)-savePreview->Width)/2), (Position.Y+1)+(((YRES/2)-savePreview->Height)/2), 255);
|
||||||
}
|
}
|
||||||
@ -465,16 +465,16 @@ void PreviewView::NotifySaveChanged(PreviewModel * sender)
|
|||||||
{
|
{
|
||||||
savePreview = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
savePreview = SaveRenderer::Ref().Render(save->GetGameSave(), false, true);
|
||||||
|
|
||||||
if(savePreview && savePreview->Buffer && !(savePreview->Width == XRES/2 && savePreview->Height == YRES/2))
|
if(savePreview && !(savePreview->Width == XRES/2 && savePreview->Height == YRES/2))
|
||||||
{
|
{
|
||||||
pixel * oldData = savePreview->Buffer;
|
|
||||||
float factorX = ((float)XRES/2)/((float)savePreview->Width);
|
float factorX = ((float)XRES/2)/((float)savePreview->Width);
|
||||||
float factorY = ((float)YRES/2)/((float)savePreview->Height);
|
float factorY = ((float)YRES/2)/((float)savePreview->Height);
|
||||||
float scaleFactor = factorY < factorX ? factorY : factorX;
|
float scaleFactor = factorY < factorX ? factorY : factorX;
|
||||||
savePreview->Buffer = Graphics::resample_img(oldData, savePreview->Width, savePreview->Height, int(savePreview->Width*scaleFactor), int(savePreview->Height*scaleFactor));
|
pixel *data = Graphics::resample_img(savePreview->Buffer.data(), savePreview->Width, savePreview->Height, int(savePreview->Width*scaleFactor), int(savePreview->Height*scaleFactor));
|
||||||
delete[] oldData;
|
|
||||||
savePreview->Width = int(savePreview->Width * scaleFactor);
|
savePreview->Width = int(savePreview->Width * scaleFactor);
|
||||||
savePreview->Height = int(savePreview->Height * scaleFactor);
|
savePreview->Height = int(savePreview->Height * scaleFactor);
|
||||||
|
savePreview->Buffer.assign(data, data + savePreview->Width * savePreview->Height);
|
||||||
|
delete[] data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!sender->GetCanOpen())
|
else if (!sender->GetCanOpen())
|
||||||
|
@ -158,7 +158,7 @@ void RenderView::OnDraw()
|
|||||||
g->clearrect(-1, -1, WINDOWW+1, WINDOWH+1);
|
g->clearrect(-1, -1, WINDOWW+1, WINDOWH+1);
|
||||||
if(ren)
|
if(ren)
|
||||||
{
|
{
|
||||||
ren->clearScreen(1.0f);
|
ren->clearScreen();
|
||||||
ren->RenderBegin();
|
ren->RenderBegin();
|
||||||
ren->RenderEnd();
|
ren->RenderEnd();
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,8 @@
|
|||||||
#include "Simulation.h"
|
#include "Simulation.h"
|
||||||
|
|
||||||
SaveRenderer::SaveRenderer(){
|
SaveRenderer::SaveRenderer(){
|
||||||
g = new Graphics();
|
|
||||||
sim = new Simulation();
|
sim = new Simulation();
|
||||||
ren = new Renderer(g, sim);
|
ren = new Renderer(sim);
|
||||||
ren->decorations_enable = true;
|
ren->decorations_enable = true;
|
||||||
ren->blackDecorations = true;
|
ren->blackDecorations = true;
|
||||||
}
|
}
|
||||||
@ -38,7 +37,6 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire,
|
|||||||
width = save->blockWidth;
|
width = save->blockWidth;
|
||||||
height = save->blockHeight;
|
height = save->blockHeight;
|
||||||
|
|
||||||
g->Clear();
|
|
||||||
sim->clear_sim();
|
sim->clear_sim();
|
||||||
|
|
||||||
if(!sim->Load(save, true))
|
if(!sim->Load(save, true))
|
||||||
@ -47,7 +45,7 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire,
|
|||||||
ren->blackDecorations = !decorations;
|
ren->blackDecorations = !decorations;
|
||||||
pixel * pData = NULL;
|
pixel * pData = NULL;
|
||||||
pixel * dst;
|
pixel * dst;
|
||||||
pixel * src = g->vid;
|
pixel * src = ren->vid;
|
||||||
|
|
||||||
ren->ClearAccumulation();
|
ren->ClearAccumulation();
|
||||||
|
|
||||||
@ -59,7 +57,7 @@ VideoBuffer * SaveRenderer::Render(GameSave * save, bool decorations, bool fire,
|
|||||||
frame--;
|
frame--;
|
||||||
ren->render_parts();
|
ren->render_parts();
|
||||||
ren->render_fire();
|
ren->render_fire();
|
||||||
ren->clearScreen(1.0f);
|
ren->clearScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,5 +84,4 @@ SaveRenderer::~SaveRenderer()
|
|||||||
{
|
{
|
||||||
delete ren;
|
delete ren;
|
||||||
delete sim;
|
delete sim;
|
||||||
delete g;
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ class Simulation;
|
|||||||
class Renderer;
|
class Renderer;
|
||||||
|
|
||||||
class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
|
class SaveRenderer: public ExplicitSingleton<SaveRenderer> {
|
||||||
Graphics * g;
|
|
||||||
Simulation * sim;
|
Simulation * sim;
|
||||||
Renderer * ren;
|
Renderer * ren;
|
||||||
std::mutex renderMutex;
|
std::mutex renderMutex;
|
||||||
|
Loading…
Reference in New Issue
Block a user