2017-01-10 15:22:32 +00:00
|
|
|
#pragma once
|
2017-01-10 14:58:09 +00:00
|
|
|
#include <memory>
|
2017-01-10 15:22:32 +00:00
|
|
|
#include <array>
|
|
|
|
#include <vector>
|
2017-05-24 09:00:01 +00:00
|
|
|
#include <list>
|
|
|
|
#include <chrono>
|
|
|
|
#include <string>
|
2017-01-10 15:22:32 +00:00
|
|
|
#include "gSP.h"
|
2017-02-12 15:21:20 +00:00
|
|
|
#include "TexrectDrawer.h"
|
2017-01-14 10:08:02 +00:00
|
|
|
#include "Graphics/ObjectHandle.h"
|
2018-05-24 14:53:00 +00:00
|
|
|
#include "Graphics/Parameters.h"
|
2017-01-10 15:22:32 +00:00
|
|
|
|
2017-01-10 14:58:09 +00:00
|
|
|
namespace graphics {
|
2017-01-15 07:57:25 +00:00
|
|
|
class CombinerProgram;
|
2017-01-10 14:58:09 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
struct CachedTexture;
|
|
|
|
struct FrameBuffer;
|
|
|
|
|
|
|
|
#define VERTBUFF_SIZE 256U
|
|
|
|
#define ELEMBUFF_SIZE 1024U
|
|
|
|
|
2021-05-09 17:31:00 +00:00
|
|
|
constexpr f32 SCREEN_SIZE_DIM = 640.0f;
|
2021-08-25 16:12:27 +00:00
|
|
|
constexpr u32 MIPMAP_TILE_WIDTH = 256u;
|
2021-05-09 17:31:00 +00:00
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
enum class DrawingState
|
|
|
|
{
|
2020-05-04 12:17:23 +00:00
|
|
|
Non,
|
|
|
|
Line,
|
|
|
|
Triangle,
|
|
|
|
ScreenSpaceTriangle,
|
|
|
|
Rect,
|
|
|
|
TexRect
|
2017-01-10 15:22:32 +00:00
|
|
|
};
|
|
|
|
|
2017-01-10 14:58:09 +00:00
|
|
|
struct RectVertex
|
|
|
|
{
|
|
|
|
float x, y, z, w;
|
|
|
|
float s0, t0, s1, t1;
|
2020-12-14 21:45:48 +00:00
|
|
|
float bc0, bc1;
|
2017-01-10 14:58:09 +00:00
|
|
|
};
|
|
|
|
|
2017-05-24 09:00:01 +00:00
|
|
|
typedef std::chrono::milliseconds Milliseconds;
|
|
|
|
|
2017-01-11 06:08:05 +00:00
|
|
|
class GraphicsDrawer
|
2017-01-10 15:22:32 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-11-14 09:54:28 +00:00
|
|
|
void addTriangle(u32 _v0, u32 _v1, u32 _v2);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
void drawTriangles();
|
|
|
|
|
2018-05-24 14:53:00 +00:00
|
|
|
void drawScreenSpaceTriangle(u32 _numVtx, graphics::DrawModeParam _mode = graphics::drawmode::TRIANGLE_STRIP);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
void drawDMATriangles(u32 _numVtx);
|
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
void drawLine(u32 _v0, u32 _v1, float _width);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
2017-03-01 04:49:58 +00:00
|
|
|
void drawRect(int _ulx, int _uly, int _lrx, int _lry);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
struct TexturedRectParams
|
|
|
|
{
|
|
|
|
float ulx, uly, lrx, lry;
|
|
|
|
float dsdx, dtdy;
|
2017-11-11 16:43:01 +00:00
|
|
|
s16 s, t;
|
2017-01-10 15:22:32 +00:00
|
|
|
bool flip, forceAjustScale, texrectCmd;
|
|
|
|
const FrameBuffer * pBuffer;
|
|
|
|
TexturedRectParams(float _ulx, float _uly, float _lrx, float _lry,
|
|
|
|
float _dsdx, float _dtdy,
|
2017-11-11 16:43:01 +00:00
|
|
|
s16 _s, s16 _t,
|
2017-01-10 15:22:32 +00:00
|
|
|
bool _flip, bool _forceAjustScale, bool _texrectCmd,
|
2017-01-14 08:57:49 +00:00
|
|
|
const FrameBuffer * _pBuffer
|
2017-01-10 15:22:32 +00:00
|
|
|
) :
|
|
|
|
ulx(_ulx), uly(_uly), lrx(_lrx), lry(_lry),
|
|
|
|
dsdx(_dsdx), dtdy(_dtdy),
|
2017-11-11 16:43:01 +00:00
|
|
|
s(_s), t(_t),
|
2017-01-10 15:22:32 +00:00
|
|
|
flip(_flip), forceAjustScale(_forceAjustScale), texrectCmd(_texrectCmd),
|
2017-01-14 08:57:49 +00:00
|
|
|
pBuffer(_pBuffer)
|
2017-01-10 15:22:32 +00:00
|
|
|
{}
|
|
|
|
private:
|
2017-01-11 06:08:05 +00:00
|
|
|
friend class GraphicsDrawer;
|
2017-01-10 15:22:32 +00:00
|
|
|
TexturedRectParams() :
|
|
|
|
ulx(0), uly(0), lrx(0), lry(0)
|
|
|
|
{};
|
|
|
|
};
|
|
|
|
|
|
|
|
void correctTexturedRectParams(TexturedRectParams & _params);
|
|
|
|
|
|
|
|
void drawTexturedRect(const TexturedRectParams & _params);
|
|
|
|
|
2017-01-14 08:58:14 +00:00
|
|
|
struct CopyRectParams
|
|
|
|
{
|
|
|
|
s32 srcX0 = 0;
|
|
|
|
s32 srcY0 = 0;
|
|
|
|
s32 srcX1;
|
|
|
|
s32 srcY1;
|
|
|
|
u32 srcWidth;
|
|
|
|
u32 srcHeight;
|
|
|
|
s32 dstX0 = 0;
|
|
|
|
s32 dstY0 = 0;
|
|
|
|
s32 dstX1;
|
|
|
|
s32 dstY1;
|
|
|
|
u32 dstWidth;
|
|
|
|
u32 dstHeight;
|
2017-03-10 04:36:03 +00:00
|
|
|
bool invertX = false;
|
|
|
|
bool invertY = false;
|
2017-12-14 16:46:45 +00:00
|
|
|
typedef std::array<CachedTexture *, 2> Textures;
|
|
|
|
Textures tex = Textures{ { nullptr, nullptr } };
|
2019-11-30 08:31:43 +00:00
|
|
|
graphics::CombinerProgram * combiner = nullptr;
|
2017-01-28 09:52:09 +00:00
|
|
|
graphics::TextureParam filter;
|
2017-01-14 08:58:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void copyTexturedRect(const CopyRectParams & _params);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
2017-01-14 10:08:02 +00:00
|
|
|
struct BlitOrCopyRectParams : public CopyRectParams
|
|
|
|
{
|
|
|
|
graphics::ObjectHandle readBuffer;
|
|
|
|
graphics::ObjectHandle drawBuffer;
|
2017-01-28 09:52:09 +00:00
|
|
|
graphics::BlitMaskParam mask;
|
2017-01-14 10:08:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
void blitOrCopyTexturedRect(const BlitOrCopyRectParams & _params);
|
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
void drawText(const char *_pText, float x, float y);
|
|
|
|
|
|
|
|
void drawOSD();
|
|
|
|
|
2017-05-24 09:00:01 +00:00
|
|
|
void showMessage(std::string _message, Milliseconds _interval);
|
|
|
|
|
2018-09-27 11:31:41 +00:00
|
|
|
void clearDepthBuffer();
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
void clearColorBuffer(float * _pColor);
|
|
|
|
|
|
|
|
int getTrianglesCount() const { return triangles.num; }
|
|
|
|
|
2021-02-25 15:00:42 +00:00
|
|
|
bool isClipped(u32 _v0, u32 _v1, u32 _v2) const;
|
2017-01-10 15:22:32 +00:00
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
bool isRejected(u32 _v0, u32 _v1, u32 _v2) const;
|
2018-12-06 09:31:40 +00:00
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
SPVertex & getVertex(u32 _v) { return triangles.vertices[_v]; }
|
|
|
|
|
2017-10-03 11:19:08 +00:00
|
|
|
SPVertex * getVertexPtr(u32 _v) { return triangles.vertices.data() + _v; }
|
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
void setDMAVerticesSize(u32 _size) { if (m_dmaVertices.size() < _size) m_dmaVertices.resize(_size); }
|
|
|
|
|
|
|
|
SPVertex * getDMAVerticesData() { return m_dmaVertices.data(); }
|
|
|
|
|
2017-09-22 08:24:00 +00:00
|
|
|
SPVertex & getCurrentDMAVertex();
|
2018-05-06 08:54:12 +00:00
|
|
|
u32 getDMAVerticesCount() const { return m_dmaVerticesNum; }
|
2017-09-22 08:24:00 +00:00
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
void updateScissor(FrameBuffer * _pBuffer) const;
|
|
|
|
|
|
|
|
DrawingState getDrawingState() const { return m_drawingState; }
|
|
|
|
|
2017-01-25 09:16:17 +00:00
|
|
|
void dropRenderState() { m_drawingState = DrawingState::Non; }
|
2017-01-10 15:22:32 +00:00
|
|
|
|
2017-01-15 07:57:25 +00:00
|
|
|
void flush() { m_texrectDrawer.draw(); }
|
|
|
|
|
2018-03-21 16:06:38 +00:00
|
|
|
bool isTexrectDrawerMode() const { return !m_texrectDrawer.isEmpty(); }
|
|
|
|
|
2018-10-12 08:01:13 +00:00
|
|
|
void setBackgroundDrawingMode(bool _mode) { m_bBGMode = _mode; }
|
|
|
|
|
2020-04-28 15:24:26 +00:00
|
|
|
void setBlendMode(bool _forceLegacyBlending = false) const;
|
|
|
|
|
2021-02-25 15:00:42 +00:00
|
|
|
void clearStatistics() { m_statistics.clear(); }
|
|
|
|
|
|
|
|
struct Statistics {
|
|
|
|
u32 fillRects = 0;
|
|
|
|
u32 texRects = 0;
|
|
|
|
u32 clippedTris = 0;
|
|
|
|
u32 rejectedTris = 0;
|
|
|
|
u32 culledTris = 0;
|
|
|
|
u32 drawnTris = 0;
|
|
|
|
u32 lines = 0;
|
|
|
|
void clear();
|
|
|
|
};
|
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
private:
|
2017-01-15 07:57:25 +00:00
|
|
|
friend class DisplayWindow;
|
2017-02-12 15:21:20 +00:00
|
|
|
friend TexrectDrawer;
|
2017-01-15 07:57:25 +00:00
|
|
|
|
|
|
|
GraphicsDrawer();
|
2017-05-24 09:00:01 +00:00
|
|
|
~GraphicsDrawer();
|
2017-01-15 07:57:25 +00:00
|
|
|
|
|
|
|
GraphicsDrawer(const GraphicsDrawer &) = delete;
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
void _initStates();
|
|
|
|
void _initData();
|
|
|
|
void _destroyData();
|
|
|
|
|
|
|
|
void _setSpecialTexrect() const;
|
|
|
|
|
2020-04-28 15:24:26 +00:00
|
|
|
void _legacyBlending() const;
|
|
|
|
void _ordinaryBlending() const;
|
|
|
|
void _dualSourceBlending() const;
|
2017-01-10 15:22:32 +00:00
|
|
|
void _updateCullFace() const;
|
2021-03-05 17:28:25 +00:00
|
|
|
void _updateViewport(const FrameBuffer * _pBuffer = nullptr, const f32 scale = 0.0f) const;
|
2017-01-10 15:22:32 +00:00
|
|
|
void _updateDepthUpdate() const;
|
|
|
|
void _updateDepthCompare() const;
|
|
|
|
void _updateTextures() const;
|
|
|
|
void _updateStates(DrawingState _drawingState) const;
|
2020-05-04 12:17:23 +00:00
|
|
|
void _prepareDrawTriangle(DrawingState _drawingState);
|
2017-01-10 15:22:32 +00:00
|
|
|
bool _canDraw() const;
|
2020-11-14 09:54:28 +00:00
|
|
|
void _drawThickLine(u32 _v0, u32 _v1, float _width);
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
void _drawOSD(const char *_pText, float _x, float & _y);
|
|
|
|
|
2017-05-24 09:00:01 +00:00
|
|
|
typedef std::list<std::string> OSDMessages;
|
|
|
|
void _removeOSDMessage(OSDMessages::iterator _iter, Milliseconds _interval);
|
|
|
|
|
2017-01-10 15:22:32 +00:00
|
|
|
DrawingState m_drawingState;
|
|
|
|
TexturedRectParams m_texrectParams;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
std::array<SPVertex, VERTBUFF_SIZE> vertices;
|
2018-02-26 19:00:59 +00:00
|
|
|
std::array<u16, ELEMBUFF_SIZE> elements;
|
2017-11-18 15:07:27 +00:00
|
|
|
u32 num = 0;
|
2020-11-14 09:54:28 +00:00
|
|
|
u32 maxElement = 0;
|
2017-01-10 15:22:32 +00:00
|
|
|
} triangles;
|
|
|
|
|
|
|
|
std::vector<SPVertex> m_dmaVertices;
|
2018-05-06 08:54:12 +00:00
|
|
|
u32 m_dmaVerticesNum;
|
2017-01-10 15:22:32 +00:00
|
|
|
|
|
|
|
RectVertex m_rect[4];
|
|
|
|
|
|
|
|
u32 m_modifyVertices;
|
|
|
|
f32 m_maxLineWidth;
|
|
|
|
bool m_bFlatColors;
|
2018-10-12 08:01:13 +00:00
|
|
|
bool m_bBGMode;
|
2017-01-11 10:07:20 +00:00
|
|
|
TexrectDrawer m_texrectDrawer;
|
2017-05-24 09:00:01 +00:00
|
|
|
OSDMessages m_osdMessages;
|
2021-02-25 15:00:42 +00:00
|
|
|
mutable Statistics m_statistics;
|
2017-01-10 15:22:32 +00:00
|
|
|
};
|