forked from Mirror/libstarlight
blend modes on bind, workaround for the clear bug (just shove a quad there in replace mode)
This commit is contained in:
parent
144510b4e7
commit
c4a75355eb
@ -1,9 +1,13 @@
|
|||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "starlight/_incLib/json.hpp"
|
#include "starlight/_incLib/json.hpp"
|
||||||
|
|
||||||
using starlight::Color;
|
using starlight::Color;
|
||||||
|
|
||||||
|
const Color Color::invalid = Color(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN());
|
||||||
|
|
||||||
const Color Color::transparent = Color(0.0f, 0.0f, 0.0f, 0.0f);
|
const Color Color::transparent = Color(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
const Color Color::white = Color(1.0f, 1.0f, 1.0f);
|
const Color Color::white = Color(1.0f, 1.0f, 1.0f);
|
||||||
const Color Color::black = Color(0.0f, 0.0f, 0.0f);
|
const Color Color::black = Color(0.0f, 0.0f, 0.0f);
|
||||||
|
@ -25,11 +25,17 @@ namespace starlight {
|
|||||||
inline bool operator != (const Color& o) const { return r != o.r || g != o.g || b != o.b || a != o.a; }
|
inline bool operator != (const Color& o) const { return r != o.r || g != o.g || b != o.b || a != o.a; }
|
||||||
|
|
||||||
inline Color operator * (const Color& o) const { return Color(r * o.r, g * o.g, b * o.b, a * o.a); }
|
inline Color operator * (const Color& o) const { return Color(r * o.r, g * o.g, b * o.b, a * o.a); }
|
||||||
|
//inline Color operator * (const float m) const { return Color(r * m, g * m, b * m, a * m); }
|
||||||
|
|
||||||
// hmm. I guess this will do ¯\_(ツ)_/¯ don't really want to force cstdint
|
// hmm. I guess this will do ¯\_(ツ)_/¯ don't really want to force cstdint
|
||||||
inline operator unsigned int() const { return (((((int)(a*255))&0xFF)<<24) | ((((int)(b*255))&0xFF)<<16) | ((((int)(g*255))&0xFF)<<8) | ((((int)(r*255))&0xFF)<<0)); }
|
inline operator unsigned int() const { return (((((int)(a*255))&0xFF)<<24) | ((((int)(b*255))&0xFF)<<16) | ((((int)(g*255))&0xFF)<<8) | ((((int)(r*255))&0xFF)<<0)); }
|
||||||
// premult: inline operator unsigned int() const { return (((((int)(a*255))&0xFF)<<24) | ((((int)(a*b*255))&0xFF)<<16) | ((((int)(a*g*255))&0xFF)<<8) | ((((int)(a*r*255))&0xFF)<<0)); }
|
// premult: inline operator unsigned int() const { return (((((int)(a*255))&0xFF)<<24) | ((((int)(a*b*255))&0xFF)<<16) | ((((int)(a*g*255))&0xFF)<<8) | ((((int)(a*r*255))&0xFF)<<0)); }
|
||||||
|
|
||||||
|
inline bool Valid() const { return a == a && r == r && g == g && b == b; }
|
||||||
|
inline explicit operator bool() const { return a == a && r == r && g == g && b == b; }
|
||||||
|
|
||||||
|
static const Color invalid;
|
||||||
|
|
||||||
static const Color transparent;
|
static const Color transparent;
|
||||||
static const Color white;
|
static const Color white;
|
||||||
static const Color black;
|
static const Color black;
|
||||||
|
@ -48,6 +48,7 @@ namespace starlight {
|
|||||||
inline Vector2 & operator -= (const Vector2 & o) { x -= o.x; y -= o.y; return *this; }
|
inline Vector2 & operator -= (const Vector2 & o) { x -= o.x; y -= o.y; return *this; }
|
||||||
inline Vector2 & operator *= (const Vector2 & o) { x *= o.x; y *= o.y; return *this; }
|
inline Vector2 & operator *= (const Vector2 & o) { x *= o.x; y *= o.y; return *this; }
|
||||||
|
|
||||||
|
inline bool Valid() const { return x == x && y == y; }
|
||||||
inline explicit operator bool() const { return x == x && y == y; }
|
inline explicit operator bool() const { return x == x && y == y; }
|
||||||
|
|
||||||
static const Vector2 invalid;
|
static const Vector2 invalid;
|
||||||
|
@ -16,6 +16,7 @@ using starlight::Vector2;
|
|||||||
using starlight::VRect;
|
using starlight::VRect;
|
||||||
using starlight::Color;
|
using starlight::Color;
|
||||||
using starlight::util::WorkerThread;
|
using starlight::util::WorkerThread;
|
||||||
|
using starlight::gfx::BlendMode;
|
||||||
using starlight::gfx::CTexture;
|
using starlight::gfx::CTexture;
|
||||||
using starlight::gfx::CRenderTarget;
|
using starlight::gfx::CRenderTarget;
|
||||||
using starlight::gfx::RenderCore;
|
using starlight::gfx::RenderCore;
|
||||||
@ -144,25 +145,49 @@ void RenderCore::EndFrame() {
|
|||||||
C3D_FrameEnd(0);
|
C3D_FrameEnd(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCore::BindTexture(C3D_Tex* tex, const Color& color) {
|
namespace {
|
||||||
|
void ApplyBlendMode(C3D_TexEnv* env, BlendMode mode) {
|
||||||
|
switch(mode) {
|
||||||
|
case BlendMode::Mask: // TODO: actually implement masking! this is just a copy of Blend right now
|
||||||
|
C3D_TexEnvOp(env, C3D_RGB, 0, 0, 0);
|
||||||
|
C3D_TexEnvOp(env, C3D_Alpha, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA, 0);
|
||||||
|
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE);
|
||||||
|
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BlendMode::Replace:
|
||||||
|
C3D_AlphaBlend(GPU_BLEND_MAX, GPU_BLEND_MAX, GPU_ONE, GPU_ZERO, GPU_ONE, GPU_ZERO); // flat replace
|
||||||
|
C3D_TexEnvOp(env, C3D_RGB, 0, 0, 0);
|
||||||
|
C3D_TexEnvOp(env, C3D_Alpha, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA, 0);
|
||||||
|
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||||
|
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case BlendMode::Blend:
|
||||||
|
C3D_AlphaBlend(GPU_BLEND_ADD, GPU_BLEND_ADD, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); // premult
|
||||||
|
C3D_TexEnvOp(env, C3D_RGB, 0, 0, 0);
|
||||||
|
C3D_TexEnvOp(env, C3D_Alpha, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA, 0); // for color, the second op was 0... but that's the same value so whatever
|
||||||
|
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE); // and for color, this was REPLACE, not sure if that actually matters
|
||||||
|
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCore::BindTexture(C3D_Tex* tex, const Color& color, BlendMode mode) {
|
||||||
C3D_TexBind(0, tex); // 0 should be correct
|
C3D_TexBind(0, tex); // 0 should be correct
|
||||||
|
|
||||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_CONSTANT, 0);
|
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_CONSTANT, 0);
|
||||||
C3D_TexEnvOp(env, C3D_RGB, 0, 0, 0);
|
ApplyBlendMode(env, mode);
|
||||||
C3D_TexEnvOp(env, C3D_Alpha, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA, 0);
|
|
||||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE);//REPLACE); // let's see...
|
|
||||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
|
|
||||||
C3D_TexEnvColor(env, color.Premultiplied());
|
C3D_TexEnvColor(env, color.Premultiplied());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCore::BindColor(const Color& color) {
|
void RenderCore::BindColor(const Color& color, BlendMode mode) {
|
||||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||||
C3D_TexEnvSrc(env, C3D_Both, GPU_CONSTANT, 0, 0);
|
C3D_TexEnvSrc(env, C3D_Both, GPU_CONSTANT, 0, 0);
|
||||||
C3D_TexEnvOp(env, C3D_RGB, 0, 0, 0);
|
ApplyBlendMode(env, mode);
|
||||||
C3D_TexEnvOp(env, C3D_Alpha, GPU_TEVOP_A_SRC_ALPHA, 0, 0);
|
|
||||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);//REPLACE); // let's see...
|
|
||||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
|
|
||||||
C3D_TexEnvColor(env, color.Premultiplied());
|
C3D_TexEnvColor(env, color.Premultiplied());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +288,7 @@ CRenderTarget::CRenderTarget(int width, int height, bool forceExact) {
|
|||||||
//Clear(Color::transparent);
|
//Clear(Color::transparent);
|
||||||
//RenderCore::BindTexture(&tex, Color::white);
|
//RenderCore::BindTexture(&tex, Color::white);
|
||||||
//C3D_FrameBufClear(&(tgt->frameBuf), C3D_CLEAR_COLOR, 0, 0);
|
//C3D_FrameBufClear(&(tgt->frameBuf), C3D_CLEAR_COLOR, 0, 0);
|
||||||
//C3D_RenderTargetSetClear(tgt, static_cast<C3D_ClearBits>(0), 0, 0);
|
C3D_RenderTargetSetClear(tgt, static_cast<C3D_ClearBits>(0), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CRenderTarget::~CRenderTarget() {
|
CRenderTarget::~CRenderTarget() {
|
||||||
@ -279,7 +304,7 @@ void CRenderTarget::Clear(Color color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CRenderTarget::BindTarget() {
|
void CRenderTarget::BindTarget() {
|
||||||
if (true || clearColor) { // clear if color valid
|
if (clearColor.Valid()) { // clear if color valid
|
||||||
unsigned int c = clearColor;
|
unsigned int c = clearColor;
|
||||||
c = ((c>>24)&0x000000FF) | ((c>>8)&0x0000FF00) | ((c<<8)&0x00FF0000) | ((c<<24)&0xFF000000); // reverse endianness
|
c = ((c>>24)&0x000000FF) | ((c>>8)&0x0000FF00) | ((c<<8)&0x00FF0000) | ((c<<24)&0xFF000000); // reverse endianness
|
||||||
//C3D_RenderTargetSetClear(tgt, static_cast<C3D_ClearBits>(0), c, 0);
|
//C3D_RenderTargetSetClear(tgt, static_cast<C3D_ClearBits>(0), c, 0);
|
||||||
@ -288,6 +313,13 @@ void CRenderTarget::BindTarget() {
|
|||||||
}
|
}
|
||||||
C3D_FrameDrawOn(tgt);
|
C3D_FrameDrawOn(tgt);
|
||||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, sLocProjection, &projection);
|
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, sLocProjection, &projection);
|
||||||
|
|
||||||
|
if (!firstClearDone) { firstClearDone = true; // workaround for faulty clearing; just draw a quad in replace mode to force the matter!
|
||||||
|
if (clearColor.Valid()) {
|
||||||
|
RenderCore::BindColor(clearColor, BlendMode::Replace);
|
||||||
|
RenderCore::DrawQuad(VRect(Vector2::zero, txSize), VRect::zero, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRenderTarget::Bind(Color color) {
|
void CRenderTarget::Bind(Color color) {
|
||||||
|
@ -14,6 +14,13 @@
|
|||||||
namespace starlight {
|
namespace starlight {
|
||||||
namespace gfx {
|
namespace gfx {
|
||||||
class RenderCore;
|
class RenderCore;
|
||||||
|
enum class BlendMode {
|
||||||
|
Blend,
|
||||||
|
Mask,
|
||||||
|
Replace,
|
||||||
|
|
||||||
|
Normal = Blend
|
||||||
|
};
|
||||||
|
|
||||||
class CTexture {
|
class CTexture {
|
||||||
protected:
|
protected:
|
||||||
@ -33,6 +40,7 @@ namespace starlight {
|
|||||||
C3D_RenderTarget* tgt;
|
C3D_RenderTarget* tgt;
|
||||||
C3D_Tex tex;
|
C3D_Tex tex;
|
||||||
Color clearColor = Color::transparent;
|
Color clearColor = Color::transparent;
|
||||||
|
bool firstClearDone = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
C3D_Mtx projection;
|
C3D_Mtx projection;
|
||||||
@ -62,8 +70,8 @@ namespace starlight {
|
|||||||
static void BeginFrame();
|
static void BeginFrame();
|
||||||
static void EndFrame();
|
static void EndFrame();
|
||||||
|
|
||||||
static void BindTexture(C3D_Tex* tex, const Color& color);
|
static void BindTexture(C3D_Tex* tex, const Color& color, BlendMode mode = BlendMode::Normal);
|
||||||
static void BindColor(const Color& color);
|
static void BindColor(const Color& color, BlendMode mode = BlendMode::Normal);
|
||||||
static void DrawQuad(const VRect& rect, const VRect& src, bool noSnap = false);
|
static void DrawQuad(const VRect& rect, const VRect& src, bool noSnap = false);
|
||||||
static void DrawQuad(const VRect& rect, const Vector2& anchor, float angle, const VRect& src);
|
static void DrawQuad(const VRect& rect, const Vector2& anchor, float angle, const VRect& src);
|
||||||
|
|
||||||
|
@ -2,7 +2,13 @@
|
|||||||
|
|
||||||
|
|
||||||
roadmap to v0.5.1 {
|
roadmap to v0.5.1 {
|
||||||
figure out how to fix the clear bug
|
- clear bug workaround implemented
|
||||||
|
^ maybe replace clearing with the workaround entirely?
|
||||||
|
implement more blend modes {
|
||||||
|
- flat replace
|
||||||
|
masking
|
||||||
|
}
|
||||||
|
|
||||||
- fix the hang on osk when pressing (L|R)+up+left
|
- fix the hang on osk when pressing (L|R)+up+left
|
||||||
figure out what (else) to put on the left side of the keyboard (opposite backspace and enter)
|
figure out what (else) to put on the left side of the keyboard (opposite backspace and enter)
|
||||||
temporary drawable loading, local themeref, discard etc.
|
temporary drawable loading, local themeref, discard etc.
|
||||||
@ -24,6 +30,7 @@ roadmap to v0.5.1 {
|
|||||||
}
|
}
|
||||||
} then by v0.5.5 {
|
} then by v0.5.5 {
|
||||||
event propagation system of some sort; threadsafe to whatever extent is needed on 3DS
|
event propagation system of some sort; threadsafe to whatever extent is needed on 3DS
|
||||||
|
figure out how to *actually* fix the clear bug...?
|
||||||
} then consider these before 1.0 "gold" {
|
} then consider these before 1.0 "gold" {
|
||||||
make closing forms a bit less finicky (add them to a separate list and let the Application remove them from the list)
|
make closing forms a bit less finicky (add them to a separate list and let the Application remove them from the list)
|
||||||
garbage collection for not-recently-used theme assets {
|
garbage collection for not-recently-used theme assets {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user