BAHAHAHAHAHAHAHAA

This commit is contained in:
Arisotura 2019-05-16 16:27:45 +02:00
parent f2282e9e32
commit c81bcccadc
11 changed files with 816 additions and 731 deletions

View File

@ -107,6 +107,7 @@
<Unit filename="src/GPU3D.cpp" />
<Unit filename="src/GPU3D.h" />
<Unit filename="src/GPU3D_OpenGL43.cpp" />
<Unit filename="src/GPU3D_OpenGL43_shaders.h" />
<Unit filename="src/GPU3D_Soft.cpp" />
<Unit filename="src/NDS.cpp" />
<Unit filename="src/NDS.h" />

View File

@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2];
int FrontBuffer;
u32* Framebuffer[2][2];
int FBScale[2];
bool Accelerated;
GPU2D* GPU2D_A;
GPU2D* GPU2D_B;
@ -88,9 +89,8 @@ bool Init()
FrontBuffer = 0;
Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL;
Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL;
FBScale[0] = -1; FBScale[1] = -1;
//SetFramebufferScale(1);
SetFramebufferScale(1, 1);
FBScale[0] = -1; FBScale[1] = -1; Accelerated = false;
SetDisplaySettings(0, 0, false);
return true;
}
@ -247,13 +247,15 @@ void AssignFramebuffers()
}
}
void SetFramebufferScale(int top, int bottom)
void SetDisplaySettings(int topscale, int bottomscale, bool accel)
{accel=true;
if (topscale != FBScale[0] || accel != Accelerated)
{
if (top != FBScale[0])
{
FBScale[0] = top;
FBScale[0] = accel ? 0 : topscale;
int fbsize = (256 * 192) << (FBScale[0] * 2);
int fbsize;
if (accel) fbsize = 256*3 * 192;
else fbsize = (256 * 192) << (FBScale[0] * 2);
if (Framebuffer[0][0]) delete[] Framebuffer[0][0];
if (Framebuffer[1][0]) delete[] Framebuffer[1][0];
Framebuffer[0][0] = new u32[fbsize];
@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom)
if (NDS::PowerControl9 & (1<<15))
{
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]);
GPU2D_A->SetScale(FBScale[0]);
GPU3D::SetScale(FBScale[0]);
GPU2D_A->SetDisplaySettings(FBScale[0], accel);
GPU3D::SetDisplaySettings(topscale, accel);
}
else
{
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]);
GPU2D_B->SetScale(FBScale[0]);
GPU2D_B->SetDisplaySettings(FBScale[0], accel);
}
}
if (bottom != FBScale[1])
if (bottomscale != FBScale[1] || accel != Accelerated)
{
FBScale[1] = bottom;
FBScale[1] = accel ? 0 : bottomscale;
int fbsize = (256 * 192) << (FBScale[1] * 2);
int fbsize;
if (accel) fbsize = 256*3 * 192;
else fbsize = (256 * 192) << (FBScale[1] * 2);
if (Framebuffer[0][1]) delete[] Framebuffer[0][1];
if (Framebuffer[1][1]) delete[] Framebuffer[1][1];
Framebuffer[0][1] = new u32[fbsize];
@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom)
if (NDS::PowerControl9 & (1<<15))
{
GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]);
GPU2D_B->SetScale(FBScale[1]);
GPU2D_B->SetDisplaySettings(FBScale[1], accel);
}
else
{
GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]);
GPU2D_A->SetScale(FBScale[1]);
GPU3D::SetScale(FBScale[1]);
GPU2D_A->SetDisplaySettings(FBScale[1], accel);
GPU3D::SetDisplaySettings(bottomscale, accel);
}
}
Accelerated = accel;
}

View File

@ -75,7 +75,7 @@ void Stop();
void DoSavestate(Savestate* file);
void SetFramebufferScale(int top, int bottom);
void SetDisplaySettings(int topscale, int bottomscale, bool accel);
void MapVRAM_AB(u32 bank, u8 cnt);

View File

@ -82,7 +82,6 @@
GPU2D::GPU2D(u32 num)
{
Num = num;
SetScale(0);
}
GPU2D::~GPU2D()
@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf)
Framebuffer = buf;
}
void GPU2D::SetScale(int scale)
void GPU2D::SetDisplaySettings(int scale, bool accel)
{
if (accel) scale = 0;
Accelerated = accel;
LineScale = scale;
LineStride = 256 << (scale*2);
if (scale == 1) DrawPixel = DrawPixel_2x;
if (Accelerated) DrawPixel = DrawPixel_Accel;
else if (scale == 1) DrawPixel = DrawPixel_2x;
else if (scale == 2) DrawPixel = DrawPixel_4x;
else DrawPixel = DrawPixel_1x;
}
@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor)
void GPU2D::DrawScanline(u32 line)
{
u32* dst = &Framebuffer[LineStride * line];
int stride = Accelerated ? (256*3) : LineStride;
u32* dst = &Framebuffer[stride * line];
int n3dline = line;
line = GPU::VCount;
@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line)
u32 dispmode = DispCnt >> 16;
dispmode &= (Num ? 0x1 : 0x3);
if (Num == 0)
if (Num == 0 && !Accelerated)
_3DLine = GPU3D::GetLine(n3dline);
// always render regular graphics
@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line)
case 0: // screen off
{
for (int i = 0; i < LineStride; i++)
dst[i] = 0xFF3F3F3F;
dst[i] = 0x003F3F3F;
}
break;
case 1: // regular display
{
for (int i = 0; i < LineStride; i+=2)
for (int i = 0; i < stride; i+=2)
*(u64*)&dst[i] = *(u64*)&BGOBJLine[i];
}
break;
@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line)
DoCapture(line, capwidth);
}
if (Accelerated) return;
// master brightness
if (dispmode != 0)
{
@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width)
u16* dst = (u16*)GPU::VRAM[dstvram];
u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width);
// TODO: handle 3D in accelerated mode!!
u32* srcA;
if (CaptureCnt & (1<<24))
srcA = _3DLine;
@ -1272,6 +1280,8 @@ void GPU2D::DrawScanline_Mode1(u32 line)
// color special effects
// can likely be optimized
if (!Accelerated)
{
u32 bldcnteffect = (BlendCnt >> 6) & 0x3;
for (int i = 0; i < LineStride; i++)
@ -1356,6 +1366,7 @@ void GPU2D::DrawScanline_Mode1(u32 line)
break;
}
}
}
if (BGMosaicY >= BGMosaicYMax)
{
@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag)
*(u64*)(dst+3072+2) = val;
}
void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag)
{
u8 r = (color & 0x001F) << 1;
u8 g = (color & 0x03E0) >> 4;
u8 b = (color & 0x7C00) >> 9;
*(dst+512) = *(dst+256);
*(dst+256) = *dst;
*dst = r | (g << 8) | (b << 16) | flag;
}
void GPU2D::DrawBG_3D()
{
u16 xoff = BGXPos[0];
@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D()
iend -= (xoff & 0xFF);
}
if (LineScale == 1)
if (Accelerated)
{
for (; i < iend; i++)
{
if (!(WindowMask[i] & 0x01)) continue;
BGOBJLine[i+512] = BGOBJLine[i+256];
BGOBJLine[i+256] = BGOBJLine[i];
BGOBJLine[i] = 0x40000000; // 3D-layer placeholder
}
}
else if (LineScale == 1)
{
for (; i < iend; i++)
{

View File

@ -31,7 +31,7 @@ public:
void SetEnabled(bool enable) { Enabled = enable; }
void SetFramebuffer(u32* buf);
void SetScale(int scale);
void SetDisplaySettings(int scale, bool accel);
u8 Read8(u32 addr);
u16 Read16(u32 addr);
@ -71,6 +71,7 @@ private:
u32 LineStride;
u32 LineScale;
bool Accelerated;
u32 BGOBJLine[1024*4 * 2];
u32* _3DLine;
@ -136,6 +137,7 @@ private:
static void DrawPixel_1x(u32* dst, u16 color, u32 flag);
static void DrawPixel_2x(u32* dst, u16 color, u32 flag);
static void DrawPixel_4x(u32* dst, u16 color, u32 flag);
static void DrawPixel_Accel(u32* dst, u16 color, u32 flag);
void (*DrawPixel)(u32* dst, u16 color, u32 flag);
void DrawBG_3D();

View File

@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering)
if (!rendering) ResetRenderingState();
}
void SetScale(int scale)
void SetDisplaySettings(int scale, bool accel)
{
GLRenderer43::SetScale(scale);
GLRenderer43::SetDisplaySettings(scale, accel);
}

View File

@ -97,7 +97,7 @@ void Reset();
void DoSavestate(Savestate* file);
void SetEnabled(bool geometry, bool rendering);
void SetScale(int scale);
void SetDisplaySettings(int scale, bool accel);
void ExecuteCommand();
@ -110,6 +110,7 @@ void VCount144();
void VBlank();
void VCount215();
u32* GetLine(int line);
void SetupAccelFrame();
void WriteToGXFIFO(u32 val);
@ -127,13 +128,14 @@ bool Init();
void DeInit();
void Reset();
void SetScale(int scale);
void SetDisplaySettings(int scale, bool accel);
void SetupRenderThread();
void VCount144();
void RenderFrame();
u32* GetLine(int line);
void SetupAccelFrame();
}
@ -144,11 +146,12 @@ bool Init();
void DeInit();
void Reset();
void SetScale(int scale);
void SetDisplaySettings(int scale, bool accel);
void VCount144();
void RenderFrame();
u32* GetLine(int line);
void SetupAccelFrame();
}

View File

@ -21,6 +21,7 @@
#include "NDS.h"
#include "GPU.h"
#include "OpenGLSupport.h"
#include "GPU3D_OpenGL43_shaders.h"
namespace GPU3D
{
@ -33,631 +34,6 @@ namespace GLRenderer43
// * UBO: 3.1
// * glMemoryBarrier: 4.2
// TODO: consider other way to handle uniforms (UBO?)
#define kShaderHeader "#version 430"
const char* kClearVS = kShaderHeader R"(
layout(location=0) in vec2 vPosition;
layout(location=1) uniform uint uDepth;
void main()
{
float fdepth = (float(uDepth) / 8388608.0) - 1.0;
gl_Position = vec4(vPosition, fdepth, 1.0);
}
)";
const char* kClearFS = kShaderHeader R"(
layout(location=0) uniform uvec4 uColor;
layout(location=2) uniform uint uOpaquePolyID;
layout(location=3) uniform uint uFogFlag;
layout(location=0) out vec4 oColor;
layout(location=1) out uvec3 oAttr;
void main()
{
oColor = vec4(uColor).bgra / 31.0;
oAttr.r = 0;
oAttr.g = uOpaquePolyID;
oAttr.b = 0;
}
)";
const char* kRenderVSCommon = R"(
layout(std140, binding=0) uniform uConfig
{
vec2 uScreenSize;
uint uDispCnt;
vec4 uToonColors[32];
};
layout(location=0) in uvec4 vPosition;
layout(location=1) in uvec4 vColor;
layout(location=2) in ivec2 vTexcoord;
layout(location=3) in uvec3 vPolygonAttr;
smooth out vec4 fColor;
smooth out vec2 fTexcoord;
flat out uvec3 fPolygonAttr;
)";
const char* kRenderFSCommon = R"(
layout(binding=0) uniform usampler2D TexMem;
layout(binding=1) uniform sampler2D TexPalMem;
layout(std140, binding=0) uniform uConfig
{
vec2 uScreenSize;
uint uDispCnt;
vec4 uToonColors[32];
};
smooth in vec4 fColor;
smooth in vec2 fTexcoord;
flat in uvec3 fPolygonAttr;
layout(location=0) out vec4 oColor;
layout(location=1) out uvec3 oAttr;
int TexcoordWrap(int c, int maxc, uint mode)
{
if ((mode & (1<<0)) != 0)
{
if ((mode & (1<<2)) != 0 && (c & maxc) != 0)
return (maxc-1) - (c & (maxc-1));
else
return (c & (maxc-1));
}
else
return clamp(c, 0, maxc-1);
}
vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.a = (pixel.r & 0xE0);
pixel.a = (pixel.a >> 3) + (pixel.a >> 6);
pixel.r &= 0x1F;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, float(pixel.a)/31.0);
}
vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) >> 2;
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.r >>= (2 * (st.x & 3));
pixel.r &= 0x03;
addr.y = (addr.y << 2) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) >> 1;
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
if ((st.x & 1) != 0) pixel.r >>= 4;
else pixel.r &= 0x0F;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3);
uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3;
int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1);
if (addr.x >= 0x40000) slot1addr += 0x10000;
uint palinfo;
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
palinfo = p.r;
slot1addr++;
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
palinfo |= (p.r << 8);
addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1);
palinfo >>= 14;
if (val == 0)
{
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (val == 1)
{
addr.y++;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (val == 2)
{
if (palinfo == 1)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb + color1.rgb) / 2.0, 1.0);
}
else if (palinfo == 3)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0);
}
else
{
addr.y += 2;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
}
else
{
if (palinfo == 2)
{
addr.y += 3;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (palinfo == 3)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0);
}
else
{
return vec4(0.0);
}
}
}
vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.a = (pixel.r & 0xF8) >> 3;
pixel.r &= 0x07;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, float(pixel.a)/31.0);
}
vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) << 1;
uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
addr.x++;
uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
vec4 color;
color.r = float(pixelL.r & 0x1F) / 31.0;
color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0;
color.b = float((pixelH.r & 0x7C) >> 2) / 31.0;
color.a = float(pixelH.r >> 7);
return color;
}
vec4 TextureLookup_Nearest(vec2 st)
{
uint attr = fPolygonAttr.y;
uint paladdr = fPolygonAttr.z;
float alpha0;
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
else alpha0 = 1.0;
int tw = 8 << int((attr >> 20) & 0x7);
int th = 8 << int((attr >> 23) & 0x7);
ivec4 st_full = ivec4(ivec2(st), tw, th);
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
uint wrapmode = attr >> 16;
uint type = (attr >> 26) & 0x7;
if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode);
else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode);
else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode);
else return TextureFetch_Direct (vramaddr, st_full, wrapmode);
}
vec4 TextureLookup_Linear(vec2 texcoord)
{
ivec2 intpart = ivec2(texcoord);
vec2 fracpart = fract(texcoord);
uint attr = fPolygonAttr.y;
uint paladdr = fPolygonAttr.z;
float alpha0;
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
else alpha0 = 1.0;
int tw = 8 << int((attr >> 20) & 0x7);
int th = 8 << int((attr >> 23) & 0x7);
ivec4 st_full = ivec4(intpart, tw, th);
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
uint wrapmode = attr >> 16;
vec4 A, B, C, D;
uint type = (attr >> 26) & 0x7;
if (type == 5)
{
A = TextureFetch_Compressed(vramaddr, st_full , wrapmode);
B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else if (type == 2)
{
A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 3)
{
A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 4)
{
A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 1)
{
A = TextureFetch_A3I5(vramaddr, st_full , wrapmode);
B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else if (type == 6)
{
A = TextureFetch_A5I3(vramaddr, st_full , wrapmode);
B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else
{
A = TextureFetch_Direct(vramaddr, st_full , wrapmode);
B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
float fx = fracpart.x;
vec4 AB;
if (A.a < (0.5/31.0) && B.a < (0.5/31.0))
AB = vec4(0);
else
{
//if (A.a < (0.5/31.0) || B.a < (0.5/31.0))
// fx = step(0.5, fx);
AB = mix(A, B, fx);
}
fx = fracpart.x;
vec4 CD;
if (C.a < (0.5/31.0) && D.a < (0.5/31.0))
CD = vec4(0);
else
{
//if (C.a < (0.5/31.0) || D.a < (0.5/31.0))
// fx = step(0.5, fx);
CD = mix(C, D, fx);
}
fx = fracpart.y;
vec4 ret;
if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0))
ret = vec4(0);
else
{
//if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0))
// fx = step(0.5, fx);
ret = mix(AB, CD, fx);
}
return ret;
}
vec4 FinalColor()
{
vec4 col;
vec4 vcol = fColor;
uint blendmode = (fPolygonAttr.x >> 4) & 0x3;
if (blendmode == 2)
{
if ((uDispCnt & (1<<1)) == 0)
{
// toon
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
vcol.rgb = tooncolor;
}
else
{
// highlight
vcol.rgb = vcol.rrr;
}
}
if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0))
{
// no texture
col = vcol;
}
else
{
vec4 tcol = TextureLookup_Nearest(fTexcoord);
//vec4 tcol = TextureLookup_Linear(fTexcoord);
if ((blendmode & 1) != 0)
{
// decal
col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a));
col.a = vcol.a;
}
else
{
// modulate
col = vcol * tcol;
}
}
if (blendmode == 2)
{
if ((uDispCnt & (1<<1)) != 0)
{
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
col.rgb = min(col.rgb + tooncolor, 1.0);
}
}
return col.bgra;
}
)";
const char* kRenderVS_Z = R"(
void main()
{
uint attr = vPolygonAttr.x;
uint zshift = (attr >> 16) & 0x1F;
vec4 fpos;
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0;
fpos.w = float(vPosition.w) / 65536.0f;
fpos.xyz *= fpos.w;
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
fTexcoord = vec2(vTexcoord) / 16.0;
fPolygonAttr = vPolygonAttr;
gl_Position = fpos;
}
)";
const char* kRenderVS_W = R"(
smooth out float fZ;
void main()
{
uint attr = vPolygonAttr.x;
uint zshift = (attr >> 16) & 0x1F;
vec4 fpos;
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
fZ = float(vPosition.z << zshift) / 16777216.0;
fpos.w = float(vPosition.w) / 65536.0f;
fpos.xy *= fpos.w;
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
fTexcoord = vec2(vTexcoord) / 16.0;
fPolygonAttr = vPolygonAttr;
gl_Position = fpos;
}
)";
const char* kRenderFS_ZO = R"(
void main()
{
vec4 col = FinalColor();
if (col.a < 30.5/31) discard;
oColor = col;
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
}
)";
const char* kRenderFS_WO = R"(
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 30.5/31) discard;
oColor = col;
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZT = R"(
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
oColor = col;
oAttr.g = 0xFF;
}
)";
const char* kRenderFS_WT = R"(
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
oColor = col;
oAttr.g = 0xFF;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZSM = R"(
void main()
{
oColor = vec4(0,0,0,1);
oAttr.g = 0xFF;
oAttr.b = 1;
}
)";
const char* kRenderFS_WSM = R"(
smooth in float fZ;
void main()
{
oColor = vec4(0,0,0,1);
oAttr.g = 0xFF;
oAttr.b = 1;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZS = R"(
layout(binding=2) uniform usampler2D iAttrTex;
//layout(origin_upper_left) in vec4 gl_FragCoord;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
if (iAttr.b != 1) discard;
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
oColor = col;
}
)";
const char* kRenderFS_WS = R"(
layout(binding=2) uniform usampler2D iAttrTex;
//layout(origin_upper_left) in vec4 gl_FragCoord;
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
if (iAttr.b != 1) discard;
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
oColor = col;
gl_FragDepth = fZ;
}
)";
enum
{
@ -721,6 +97,7 @@ GLuint TexMemID;
GLuint TexPalMemID;
int ScaleFactor;
bool Accelerated;
int ScreenW, ScreenH;
GLuint FramebufferTex[4];
@ -968,9 +345,10 @@ void Reset()
//
}
void SetScale(int scale)
void SetDisplaySettings(int scale, bool accel)
{
ScaleFactor = scale;
Accelerated = accel;
// TODO: antialiasing setting
ScreenW = 256 << scale;
@ -986,10 +364,12 @@ void SetScale(int scale)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID);
glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ);
if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ);
else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ);
if (Framebuffer) delete[] Framebuffer;
Framebuffer = new u32[ScreenW*ScreenH];
if (accel) Framebuffer = new u32[256*192];
else Framebuffer = new u32[ScreenW*ScreenH];
}
@ -1533,5 +913,10 @@ u32* GetLine(int line)
return &Framebuffer[stride * line];
}
void SetupAccelFrame()
{
//
}
}
}

View File

@ -0,0 +1,645 @@
/*
Copyright 2016-2019 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef GPU3D_OPENGL43_SHADERS_H
#define GPU3D_OPENGL43_SHADERS_H
#define kShaderHeader "#version 430"
const char* kClearVS = kShaderHeader R"(
layout(location=0) in vec2 vPosition;
layout(location=1) uniform uint uDepth;
void main()
{
float fdepth = (float(uDepth) / 8388608.0) - 1.0;
gl_Position = vec4(vPosition, fdepth, 1.0);
}
)";
const char* kClearFS = kShaderHeader R"(
layout(location=0) uniform uvec4 uColor;
layout(location=2) uniform uint uOpaquePolyID;
layout(location=3) uniform uint uFogFlag;
layout(location=0) out vec4 oColor;
layout(location=1) out uvec3 oAttr;
void main()
{
oColor = vec4(uColor).bgra / 31.0;
oAttr.r = 0;
oAttr.g = uOpaquePolyID;
oAttr.b = 0;
}
)";
const char* kRenderVSCommon = R"(
layout(std140, binding=0) uniform uConfig
{
vec2 uScreenSize;
uint uDispCnt;
vec4 uToonColors[32];
};
layout(location=0) in uvec4 vPosition;
layout(location=1) in uvec4 vColor;
layout(location=2) in ivec2 vTexcoord;
layout(location=3) in uvec3 vPolygonAttr;
smooth out vec4 fColor;
smooth out vec2 fTexcoord;
flat out uvec3 fPolygonAttr;
)";
const char* kRenderFSCommon = R"(
layout(binding=0) uniform usampler2D TexMem;
layout(binding=1) uniform sampler2D TexPalMem;
layout(std140, binding=0) uniform uConfig
{
vec2 uScreenSize;
uint uDispCnt;
vec4 uToonColors[32];
};
smooth in vec4 fColor;
smooth in vec2 fTexcoord;
flat in uvec3 fPolygonAttr;
layout(location=0) out vec4 oColor;
layout(location=1) out uvec3 oAttr;
int TexcoordWrap(int c, int maxc, uint mode)
{
if ((mode & (1<<0)) != 0)
{
if ((mode & (1<<2)) != 0 && (c & maxc) != 0)
return (maxc-1) - (c & (maxc-1));
else
return (c & (maxc-1));
}
else
return clamp(c, 0, maxc-1);
}
vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.a = (pixel.r & 0xE0);
pixel.a = (pixel.a >> 3) + (pixel.a >> 6);
pixel.r &= 0x1F;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, float(pixel.a)/31.0);
}
vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) >> 2;
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.r >>= (2 * (st.x & 3));
pixel.r &= 0x03;
addr.y = (addr.y << 2) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) >> 1;
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
if ((st.x & 1) != 0) pixel.r >>= 4;
else pixel.r &= 0x0F;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, max(step(1,pixel.r),alpha0));
}
vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3);
uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3;
int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1);
if (addr.x >= 0x40000) slot1addr += 0x10000;
uint palinfo;
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
palinfo = p.r;
slot1addr++;
p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0);
palinfo |= (p.r << 8);
addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1);
palinfo >>= 14;
if (val == 0)
{
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (val == 1)
{
addr.y++;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (val == 2)
{
if (palinfo == 1)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb + color1.rgb) / 2.0, 1.0);
}
else if (palinfo == 3)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0);
}
else
{
addr.y += 2;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
}
else
{
if (palinfo == 2)
{
addr.y += 3;
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, 1.0);
}
else if (palinfo == 3)
{
vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
addr.y++;
vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0);
}
else
{
return vec4(0.0);
}
}
}
vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x);
uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
pixel.a = (pixel.r & 0xF8) >> 3;
pixel.r &= 0x07;
addr.y = (addr.y << 3) + int(pixel.r);
vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0);
return vec4(color.rgb, float(pixel.a)/31.0);
}
vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode)
{
st.x = TexcoordWrap(st.x, st.z, wrapmode>>0);
st.y = TexcoordWrap(st.y, st.w, wrapmode>>1);
addr.x += ((st.y * st.z) + st.x) << 1;
uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
addr.x++;
uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0);
vec4 color;
color.r = float(pixelL.r & 0x1F) / 31.0;
color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0;
color.b = float((pixelH.r & 0x7C) >> 2) / 31.0;
color.a = float(pixelH.r >> 7);
return color;
}
vec4 TextureLookup_Nearest(vec2 st)
{
uint attr = fPolygonAttr.y;
uint paladdr = fPolygonAttr.z;
float alpha0;
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
else alpha0 = 1.0;
int tw = 8 << int((attr >> 20) & 0x7);
int th = 8 << int((attr >> 23) & 0x7);
ivec4 st_full = ivec4(ivec2(st), tw, th);
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
uint wrapmode = attr >> 16;
uint type = (attr >> 26) & 0x7;
if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode);
else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0);
else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode);
else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode);
else return TextureFetch_Direct (vramaddr, st_full, wrapmode);
}
vec4 TextureLookup_Linear(vec2 texcoord)
{
ivec2 intpart = ivec2(texcoord);
vec2 fracpart = fract(texcoord);
uint attr = fPolygonAttr.y;
uint paladdr = fPolygonAttr.z;
float alpha0;
if ((attr & (1<<29)) != 0) alpha0 = 0.0;
else alpha0 = 1.0;
int tw = 8 << int((attr >> 20) & 0x7);
int th = 8 << int((attr >> 23) & 0x7);
ivec4 st_full = ivec4(intpart, tw, th);
ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr));
uint wrapmode = attr >> 16;
vec4 A, B, C, D;
uint type = (attr >> 26) & 0x7;
if (type == 5)
{
A = TextureFetch_Compressed(vramaddr, st_full , wrapmode);
B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else if (type == 2)
{
A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 3)
{
A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 4)
{
A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0);
B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0);
C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0);
D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0);
}
else if (type == 1)
{
A = TextureFetch_A3I5(vramaddr, st_full , wrapmode);
B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else if (type == 6)
{
A = TextureFetch_A5I3(vramaddr, st_full , wrapmode);
B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
else
{
A = TextureFetch_Direct(vramaddr, st_full , wrapmode);
B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode);
C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode);
D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode);
}
float fx = fracpart.x;
vec4 AB;
if (A.a < (0.5/31.0) && B.a < (0.5/31.0))
AB = vec4(0);
else
{
//if (A.a < (0.5/31.0) || B.a < (0.5/31.0))
// fx = step(0.5, fx);
AB = mix(A, B, fx);
}
fx = fracpart.x;
vec4 CD;
if (C.a < (0.5/31.0) && D.a < (0.5/31.0))
CD = vec4(0);
else
{
//if (C.a < (0.5/31.0) || D.a < (0.5/31.0))
// fx = step(0.5, fx);
CD = mix(C, D, fx);
}
fx = fracpart.y;
vec4 ret;
if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0))
ret = vec4(0);
else
{
//if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0))
// fx = step(0.5, fx);
ret = mix(AB, CD, fx);
}
return ret;
}
vec4 FinalColor()
{
vec4 col;
vec4 vcol = fColor;
uint blendmode = (fPolygonAttr.x >> 4) & 0x3;
if (blendmode == 2)
{
if ((uDispCnt & (1<<1)) == 0)
{
// toon
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
vcol.rgb = tooncolor;
}
else
{
// highlight
vcol.rgb = vcol.rrr;
}
}
if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0))
{
// no texture
col = vcol;
}
else
{
vec4 tcol = TextureLookup_Nearest(fTexcoord);
//vec4 tcol = TextureLookup_Linear(fTexcoord);
if ((blendmode & 1) != 0)
{
// decal
col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a));
col.a = vcol.a;
}
else
{
// modulate
col = vcol * tcol;
}
}
if (blendmode == 2)
{
if ((uDispCnt & (1<<1)) != 0)
{
vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb;
col.rgb = min(col.rgb + tooncolor, 1.0);
}
}
return col.bgra;
}
)";
const char* kRenderVS_Z = R"(
void main()
{
uint attr = vPolygonAttr.x;
uint zshift = (attr >> 16) & 0x1F;
vec4 fpos;
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0;
fpos.w = float(vPosition.w) / 65536.0f;
fpos.xyz *= fpos.w;
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
fTexcoord = vec2(vTexcoord) / 16.0;
fPolygonAttr = vPolygonAttr;
gl_Position = fpos;
}
)";
const char* kRenderVS_W = R"(
smooth out float fZ;
void main()
{
uint attr = vPolygonAttr.x;
uint zshift = (attr >> 16) & 0x1F;
vec4 fpos;
fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0;
fZ = float(vPosition.z << zshift) / 16777216.0;
fpos.w = float(vPosition.w) / 65536.0f;
fpos.xy *= fpos.w;
fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0);
fTexcoord = vec2(vTexcoord) / 16.0;
fPolygonAttr = vPolygonAttr;
gl_Position = fpos;
}
)";
const char* kRenderFS_ZO = R"(
void main()
{
vec4 col = FinalColor();
if (col.a < 30.5/31) discard;
oColor = col;
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
}
)";
const char* kRenderFS_WO = R"(
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 30.5/31) discard;
oColor = col;
oAttr.g = (fPolygonAttr.x >> 24) & 0x3F;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZT = R"(
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
oColor = col;
oAttr.g = 0xFF;
}
)";
const char* kRenderFS_WT = R"(
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
oColor = col;
oAttr.g = 0xFF;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZSM = R"(
void main()
{
oColor = vec4(0,0,0,1);
oAttr.g = 0xFF;
oAttr.b = 1;
}
)";
const char* kRenderFS_WSM = R"(
smooth in float fZ;
void main()
{
oColor = vec4(0,0,0,1);
oAttr.g = 0xFF;
oAttr.b = 1;
gl_FragDepth = fZ;
}
)";
const char* kRenderFS_ZS = R"(
layout(binding=2) uniform usampler2D iAttrTex;
//layout(origin_upper_left) in vec4 gl_FragCoord;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
if (iAttr.b != 1) discard;
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
oColor = col;
}
)";
const char* kRenderFS_WS = R"(
layout(binding=2) uniform usampler2D iAttrTex;
//layout(origin_upper_left) in vec4 gl_FragCoord;
smooth in float fZ;
void main()
{
vec4 col = FinalColor();
if (col.a < 0.5/31) discard;
if (col.a >= 30.5/31) discard;
uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0);
if (iAttr.b != 1) discard;
if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard;
oColor = col;
gl_FragDepth = fZ;
}
)";
#endif // GPU3D_OPENGL43_SHADERS_H

View File

@ -138,7 +138,7 @@ void Reset()
SetupRenderThread();
}
void SetScale(int scale)
void SetDisplaySettings(int scale, bool accel)
{
printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n");
}
@ -2122,5 +2122,10 @@ u32* GetLine(int line)
return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset];
}
void SetupAccelFrame()
{
// TODO
}
}
}

View File

@ -240,8 +240,8 @@ void GLDrawing_DrawScreen()
x1 = TopScreenRect.X + TopScreenRect.Width;
y1 = TopScreenRect.Y + TopScreenRect.Height;
scwidth = 256 << ScreenScale[0];
scheight = 192 << ScreenScale[0];
scwidth = 256;// << ScreenScale[0];
scheight = 192;// << ScreenScale[0];
switch (ScreenRotation)
{
@ -286,8 +286,8 @@ void GLDrawing_DrawScreen()
x1 = BottomScreenRect.X + BottomScreenRect.Width;
y1 = BottomScreenRect.Y + BottomScreenRect.Height;
scwidth = 256 << ScreenScale[1];
scheight = 192 << ScreenScale[1];
scwidth = 256;// << ScreenScale[1];
scheight = 192;// << ScreenScale[1];
switch (ScreenRotation)
{
@ -349,9 +349,13 @@ void GLDrawing_DrawScreen()
int frontbuf = GPU::FrontBuffer;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER,
/*glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<<ScreenScale[0], 192<<ScreenScale[0], GL_RGBA_INTEGER,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<<ScreenScale[1], 192<<ScreenScale[1], GL_RGBA_INTEGER,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);*/
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3, 192, GL_RGBA_INTEGER,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3, 192, GL_RGBA_INTEGER,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID);
@ -633,7 +637,8 @@ int EmuThreadFunc(void* burp)
ScreenScale[0] = ScreenScale[2];
ScreenScale[1] = ScreenScale[2];
int lastscale[2] = {-1, -1};
int lastscale[2] = {ScreenScale[0], ScreenScale[1]};
GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false);
Touching = false;
KeyInputMask = 0xFFF;
@ -782,7 +787,7 @@ int EmuThreadFunc(void* burp)
if (ScreenScale[0] != lastscale[0] ||
ScreenScale[1] != lastscale[1])
{
GPU::SetFramebufferScale(ScreenScale[0], ScreenScale[1]);
GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false);
ScreenDrawInited = false;
}