Fix renderer selection issue in gui. Use raw strings for shader source

This commit is contained in:
Flyinghead 2019-10-23 19:23:19 +02:00
parent 07958f08ae
commit 5e4dacfa67
4 changed files with 1006 additions and 998 deletions

View File

@ -22,275 +22,279 @@ GLuint pixel_buffer_size = 512 * 1024 * 1024; // Initial size 512 MB
#define MAX_PIXELS_PER_FRAGMENT "32"
static const char *final_shader_source = SHADER_HEADER "\
#define DEPTH_SORTED %d \n\
#define MAX_PIXELS_PER_FRAGMENT " MAX_PIXELS_PER_FRAGMENT " \n\
\n\
layout(binding = 0) uniform sampler2D tex; \n\
uniform highp float shade_scale_factor; \n\
\n\
out vec4 FragColor; \n\
\n\
uint pixel_list[MAX_PIXELS_PER_FRAGMENT]; \n\
\n\
\n\
int fillAndSortFragmentArray(ivec2 coords) \n\
{ \n\
// Load fragments into a local memory array for sorting \n\
uint idx = imageLoad(abufferPointerImg, coords).x; \n\
int count = 0; \n\
for (; idx != EOL && count < MAX_PIXELS_PER_FRAGMENT; count++) \n\
{ \n\
const Pixel p = pixels[idx]; \n\
int j = count - 1; \n\
Pixel jp = pixels[pixel_list[j]]; \n\
#if DEPTH_SORTED == 1 \n\
while (j >= 0 \n\
&& (jp.depth > p.depth \n\
|| (jp.depth == p.depth && getPolyNumber(jp) > getPolyNumber(p)))) \n\
#else \n\
while (j >= 0 && getPolyNumber(jp) > getPolyNumber(p)) \n\
#endif \n\
{ \n\
pixel_list[j + 1] = pixel_list[j]; \n\
j--; \n\
jp = pixels[pixel_list[j]]; \n\
} \n\
pixel_list[j + 1] = idx; \n\
idx = p.next; \n\
} \n\
return count; \n\
} \n\
\n\
// Blend fragments back-to-front \n\
vec4 resolveAlphaBlend(ivec2 coords) { \n\
\n\
// Copy and sort fragments into a local array \n\
int num_frag = fillAndSortFragmentArray(coords); \n\
\n\
vec4 finalColor = texture(tex, gl_FragCoord.xy / textureSize(tex, 0)); \n\
vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer \n\
float depth = 1.0; \n\
\n\
bool do_depth_test = false; \n\
for (int i = 0; i < num_frag; i++) \n\
{ \n\
const Pixel pixel = pixels[pixel_list[i]]; \n\
const PolyParam pp = tr_poly_params[getPolyNumber(pixel)]; \n\
#if DEPTH_SORTED != 1 \n\
const float frag_depth = pixel.depth; \n\
if (do_depth_test) \n\
{ \n\
switch (getDepthFunc(pp)) \n\
{ \n\
case 0: // Never \n\
continue; \n\
case 1: // Less \n\
if (frag_depth >= depth) \n\
continue; \n\
break; \n\
case 2: // Equal \n\
if (frag_depth != depth) \n\
continue; \n\
break; \n\
case 3: // Less or equal \n\
if (frag_depth > depth) \n\
continue; \n\
break; \n\
case 4: // Greater \n\
if (frag_depth <= depth) \n\
continue; \n\
break; \n\
case 5: // Not equal \n\
if (frag_depth == depth) \n\
continue; \n\
break; \n\
case 6: // Greater or equal \n\
if (frag_depth < depth) \n\
continue; \n\
break; \n\
case 7: // Always \n\
break; \n\
} \n\
} \n\
\n\
if (getDepthMask(pp)) \n\
{ \n\
depth = frag_depth; \n\
do_depth_test = true; \n\
} \n\
#endif \n\
bool area1 = false; \n\
bool shadowed = false; \n\
if (isShadowed(pixel)) \n\
{ \n\
if (isTwoVolumes(pp)) \n\
area1 = true; \n\
else \n\
shadowed = true; \n\
} \n\
vec4 srcColor; \n\
if (getSrcSelect(pp, area1)) \n\
srcColor = secondaryBuffer; \n\
else \n\
{ \n\
srcColor = pixel.color; \n\
if (shadowed) \n\
srcColor.rgb *= shade_scale_factor; \n\
} \n\
vec4 dstColor = getDstSelect(pp, area1) ? secondaryBuffer : finalColor; \n\
vec4 srcCoef; \n\
vec4 dstCoef; \n\
\n\
int srcBlend = getSrcBlendFunc(pp, area1); \n\
switch (srcBlend) \n\
{ \n\
case ZERO: \n\
srcCoef = vec4(0.0); \n\
break; \n\
case ONE: \n\
srcCoef = vec4(1.0); \n\
break; \n\
case OTHER_COLOR: \n\
srcCoef = finalColor; \n\
break; \n\
case INVERSE_OTHER_COLOR: \n\
srcCoef = vec4(1.0) - dstColor; \n\
break; \n\
case SRC_ALPHA: \n\
srcCoef = vec4(srcColor.a); \n\
break; \n\
case INVERSE_SRC_ALPHA: \n\
srcCoef = vec4(1.0 - srcColor.a); \n\
break; \n\
case DST_ALPHA: \n\
srcCoef = vec4(dstColor.a); \n\
break; \n\
case INVERSE_DST_ALPHA: \n\
srcCoef = vec4(1.0 - dstColor.a); \n\
break; \n\
} \n\
int dstBlend = getDstBlendFunc(pp, area1); \n\
switch (dstBlend) \n\
{ \n\
case ZERO: \n\
dstCoef = vec4(0.0); \n\
break; \n\
case ONE: \n\
dstCoef = vec4(1.0); \n\
break; \n\
case OTHER_COLOR: \n\
dstCoef = srcColor; \n\
break; \n\
case INVERSE_OTHER_COLOR: \n\
dstCoef = vec4(1.0) - srcColor; \n\
break; \n\
case SRC_ALPHA: \n\
dstCoef = vec4(srcColor.a); \n\
break; \n\
case INVERSE_SRC_ALPHA: \n\
dstCoef = vec4(1.0 - srcColor.a); \n\
break; \n\
case DST_ALPHA: \n\
dstCoef = vec4(dstColor.a); \n\
break; \n\
case INVERSE_DST_ALPHA: \n\
dstCoef = vec4(1.0 - dstColor.a); \n\
break; \n\
} \n\
const vec4 result = clamp(dstColor * dstCoef + srcColor * srcCoef, 0.0, 1.0); \n\
if (getDstSelect(pp, area1)) \n\
secondaryBuffer = result; \n\
else \n\
finalColor = result; \n\
} \n\
\n\
return finalColor; \n\
\n\
} \n\
\n\
void main(void) \n\
{ \n\
ivec2 coords = ivec2(gl_FragCoord.xy); \n\
// Compute and output final color for the frame buffer \n\
// Visualize the number of layers in use \n\
//FragColor = vec4(float(fillAndSortFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT * 4, 0, 0, 1); \n\
FragColor = resolveAlphaBlend(coords); \n\
} \n\
";
static const char *final_shader_source = SHADER_HEADER
"#define MAX_PIXELS_PER_FRAGMENT " MAX_PIXELS_PER_FRAGMENT
R"(
#define DEPTH_SORTED %d
static const char *clear_shader_source = SHADER_HEADER "\
\n\
void main(void) \n\
{ \n\
ivec2 coords = ivec2(gl_FragCoord.xy); \n\
\n\
// Reset pointers \n\
imageStore(abufferPointerImg, coords, uvec4(EOL)); \n\
\n\
// Discard fragment so nothing is written to the framebuffer \n\
discard; \n\
} \n\
";
layout(binding = 0) uniform sampler2D tex;
uniform highp float shade_scale_factor;
static const char *tr_modvol_shader_source = SHADER_HEADER "\
#define MV_MODE %d \n\
#define MAX_PIXELS_PER_FRAGMENT " MAX_PIXELS_PER_FRAGMENT " \n\
\n\
// Must match ModifierVolumeMode enum values \n\
#define MV_XOR 0 \n\
#define MV_OR 1 \n\
#define MV_INCLUSION 2 \n\
#define MV_EXCLUSION 3 \n\
\n\
void main(void) \n\
{ \n\
#if MV_MODE == MV_XOR || MV_MODE == MV_OR \n\
setFragDepth(); \n\
#endif \n\
ivec2 coords = ivec2(gl_FragCoord.xy); \n\
\n\
uint idx = imageLoad(abufferPointerImg, coords).x; \n\
int list_len = 0; \n\
while (idx != EOL && list_len < MAX_PIXELS_PER_FRAGMENT) \n\
{ \n\
const Pixel pixel = pixels[idx]; \n\
const PolyParam pp = tr_poly_params[getPolyNumber(pixel)]; \n\
if (getShadowEnable(pp)) \n\
{ \n\
#if MV_MODE == MV_XOR \n\
if (gl_FragDepth >= pixel.depth) \n\
atomicXor(pixels[idx].seq_num, SHADOW_STENCIL); \n\
#elif MV_MODE == MV_OR \n\
if (gl_FragDepth >= pixel.depth) \n\
atomicOr(pixels[idx].seq_num, SHADOW_STENCIL); \n\
#elif MV_MODE == MV_INCLUSION \n\
uint prev_val = atomicAnd(pixels[idx].seq_num, ~(SHADOW_STENCIL)); \n\
if ((prev_val & (SHADOW_STENCIL|SHADOW_ACC)) == SHADOW_STENCIL) \n\
pixels[idx].seq_num = bitfieldInsert(pixel.seq_num, 1u, 31, 1); \n\
#elif MV_MODE == MV_EXCLUSION \n\
uint prev_val = atomicAnd(pixels[idx].seq_num, ~(SHADOW_STENCIL|SHADOW_ACC)); \n\
if ((prev_val & (SHADOW_STENCIL|SHADOW_ACC)) == SHADOW_ACC) \n\
pixels[idx].seq_num = bitfieldInsert(pixel.seq_num, 1u, 31, 1); \n\
#endif \n\
} \n\
idx = pixel.next; \n\
list_len++; \n\
} \n\
\n\
discard; \n\
} \n\
";
out vec4 FragColor;
uint pixel_list[MAX_PIXELS_PER_FRAGMENT];
int fillAndSortFragmentArray(ivec2 coords)
{
// Load fragments into a local memory array for sorting
uint idx = imageLoad(abufferPointerImg, coords).x;
int count = 0;
for (; idx != EOL && count < MAX_PIXELS_PER_FRAGMENT; count++)
{
const Pixel p = pixels[idx];
int j = count - 1;
Pixel jp = pixels[pixel_list[j]];
#if DEPTH_SORTED == 1
while (j >= 0
&& (jp.depth > p.depth
|| (jp.depth == p.depth && getPolyNumber(jp) > getPolyNumber(p))))
#else
while (j >= 0 && getPolyNumber(jp) > getPolyNumber(p))
#endif
{
pixel_list[j + 1] = pixel_list[j];
j--;
jp = pixels[pixel_list[j]];
}
pixel_list[j + 1] = idx;
idx = p.next;
}
return count;
}
// Blend fragments back-to-front
vec4 resolveAlphaBlend(ivec2 coords) {
// Copy and sort fragments into a local array
int num_frag = fillAndSortFragmentArray(coords);
vec4 finalColor = texture(tex, gl_FragCoord.xy / textureSize(tex, 0));
vec4 secondaryBuffer = vec4(0.0); // Secondary accumulation buffer
float depth = 1.0;
bool do_depth_test = false;
for (int i = 0; i < num_frag; i++)
{
const Pixel pixel = pixels[pixel_list[i]];
const PolyParam pp = tr_poly_params[getPolyNumber(pixel)];
#if DEPTH_SORTED != 1
const float frag_depth = pixel.depth;
if (do_depth_test)
{
switch (getDepthFunc(pp))
{
case 0: // Never
continue;
case 1: // Less
if (frag_depth >= depth)
continue;
break;
case 2: // Equal
if (frag_depth != depth)
continue;
break;
case 3: // Less or equal
if (frag_depth > depth)
continue;
break;
case 4: // Greater
if (frag_depth <= depth)
continue;
break;
case 5: // Not equal
if (frag_depth == depth)
continue;
break;
case 6: // Greater or equal
if (frag_depth < depth)
continue;
break;
case 7: // Always
break;
}
}
if (getDepthMask(pp))
{
depth = frag_depth;
do_depth_test = true;
}
#endif
bool area1 = false;
bool shadowed = false;
if (isShadowed(pixel))
{
if (isTwoVolumes(pp))
area1 = true;
else
shadowed = true;
}
vec4 srcColor;
if (getSrcSelect(pp, area1))
srcColor = secondaryBuffer;
else
{
srcColor = pixel.color;
if (shadowed)
srcColor.rgb *= shade_scale_factor;
}
vec4 dstColor = getDstSelect(pp, area1) ? secondaryBuffer : finalColor;
vec4 srcCoef;
vec4 dstCoef;
int srcBlend = getSrcBlendFunc(pp, area1);
switch (srcBlend)
{
case ZERO:
srcCoef = vec4(0.0);
break;
case ONE:
srcCoef = vec4(1.0);
break;
case OTHER_COLOR:
srcCoef = finalColor;
break;
case INVERSE_OTHER_COLOR:
srcCoef = vec4(1.0) - dstColor;
break;
case SRC_ALPHA:
srcCoef = vec4(srcColor.a);
break;
case INVERSE_SRC_ALPHA:
srcCoef = vec4(1.0 - srcColor.a);
break;
case DST_ALPHA:
srcCoef = vec4(dstColor.a);
break;
case INVERSE_DST_ALPHA:
srcCoef = vec4(1.0 - dstColor.a);
break;
}
int dstBlend = getDstBlendFunc(pp, area1);
switch (dstBlend)
{
case ZERO:
dstCoef = vec4(0.0);
break;
case ONE:
dstCoef = vec4(1.0);
break;
case OTHER_COLOR:
dstCoef = srcColor;
break;
case INVERSE_OTHER_COLOR:
dstCoef = vec4(1.0) - srcColor;
break;
case SRC_ALPHA:
dstCoef = vec4(srcColor.a);
break;
case INVERSE_SRC_ALPHA:
dstCoef = vec4(1.0 - srcColor.a);
break;
case DST_ALPHA:
dstCoef = vec4(dstColor.a);
break;
case INVERSE_DST_ALPHA:
dstCoef = vec4(1.0 - dstColor.a);
break;
}
const vec4 result = clamp(dstColor * dstCoef + srcColor * srcCoef, 0.0, 1.0);
if (getDstSelect(pp, area1))
secondaryBuffer = result;
else
finalColor = result;
}
return finalColor;
}
void main(void)
{
ivec2 coords = ivec2(gl_FragCoord.xy);
// Compute and output final color for the frame buffer
// Visualize the number of layers in use
//FragColor = vec4(float(fillAndSortFragmentArray(coords)) / MAX_PIXELS_PER_FRAGMENT * 4, 0, 0, 1);
FragColor = resolveAlphaBlend(coords);
}
)";
static const char *clear_shader_source = SHADER_HEADER
R"(
void main(void)
{
ivec2 coords = ivec2(gl_FragCoord.xy);
// Reset pointers
imageStore(abufferPointerImg, coords, uvec4(EOL));
// Discard fragment so nothing is written to the framebuffer
discard;
}
)";
static const char *tr_modvol_shader_source = SHADER_HEADER
"#define MAX_PIXELS_PER_FRAGMENT " MAX_PIXELS_PER_FRAGMENT
R"(
#define MV_MODE %d
// Must match ModifierVolumeMode enum values
#define MV_XOR 0
#define MV_OR 1
#define MV_INCLUSION 2
#define MV_EXCLUSION 3
void main(void)
{
#if MV_MODE == MV_XOR || MV_MODE == MV_OR
setFragDepth();
#endif
ivec2 coords = ivec2(gl_FragCoord.xy);
uint idx = imageLoad(abufferPointerImg, coords).x;
int list_len = 0;
while (idx != EOL && list_len < MAX_PIXELS_PER_FRAGMENT)
{
const Pixel pixel = pixels[idx];
const PolyParam pp = tr_poly_params[getPolyNumber(pixel)];
if (getShadowEnable(pp))
{
#if MV_MODE == MV_XOR
if (gl_FragDepth >= pixel.depth)
atomicXor(pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_OR
if (gl_FragDepth >= pixel.depth)
atomicOr(pixels[idx].seq_num, SHADOW_STENCIL);
#elif MV_MODE == MV_INCLUSION
uint prev_val = atomicAnd(pixels[idx].seq_num, ~(SHADOW_STENCIL));
if ((prev_val & (SHADOW_STENCIL|SHADOW_ACC)) == SHADOW_STENCIL)
pixels[idx].seq_num = bitfieldInsert(pixel.seq_num, 1u, 31, 1);
#elif MV_MODE == MV_EXCLUSION
uint prev_val = atomicAnd(pixels[idx].seq_num, ~(SHADOW_STENCIL|SHADOW_ACC));
if ((prev_val & (SHADOW_STENCIL|SHADOW_ACC)) == SHADOW_ACC)
pixels[idx].seq_num = bitfieldInsert(pixel.seq_num, 1u, 31, 1);
#endif
}
idx = pixel.next;
list_len++;
}
discard;
}
)";
static const char* VertexShaderSource =
"#version 430 \n"
"\
in highp vec3 in_pos; \n\
\n\
void main() \n\
{ \n\
gl_Position = vec4(in_pos, 1.0); \n\
}";
R"(
#version 430
in highp vec3 in_pos;
void main()
{
gl_Position = vec4(in_pos, 1.0);
}
)";
void initABuffer()
{

View File

@ -12,384 +12,384 @@
//Fragment and vertex shaders code
static const char* VertexShaderSource =
"\
#version 140 \n\
#define pp_Gouraud %d \n\
\n\
#if pp_Gouraud == 0 \n\
#define INTERPOLATION flat \n\
#else \n\
#define INTERPOLATION smooth \n\
#endif \n\
\n\
/* Vertex constants*/ \n\
uniform highp vec4 scale; \n\
uniform highp mat4 normal_matrix; \n\
/* Vertex input */ \n\
in highp vec4 in_pos; \n\
in lowp vec4 in_base; \n\
in lowp vec4 in_offs; \n\
in mediump vec2 in_uv; \n\
in lowp vec4 in_base1; \n\
in lowp vec4 in_offs1; \n\
in mediump vec2 in_uv1; \n\
/* output */ \n\
INTERPOLATION out lowp vec4 vtx_base; \n\
INTERPOLATION out lowp vec4 vtx_offs; \n\
out mediump vec2 vtx_uv; \n\
INTERPOLATION out lowp vec4 vtx_base1; \n\
INTERPOLATION out lowp vec4 vtx_offs1; \n\
out mediump vec2 vtx_uv1; \n\
void main() \n\
{ \n\
vtx_base = in_base; \n\
vtx_offs = in_offs; \n\
vtx_uv = in_uv; \n\
vtx_base1 = in_base1; \n\
vtx_offs1 = in_offs1; \n\
vtx_uv1 = in_uv1; \n\
vec4 vpos = in_pos; \n\
if (vpos.z < 0.0 || vpos.z > 3.4e37) \n\
{ \n\
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z); \n\
return; \n\
} \n\
\n\
vpos = normal_matrix * vpos; \n\
vpos.w = 1.0 / vpos.z; \n\
vpos.z = vpos.w; \n\
vpos.xy *= vpos.w; \n\
gl_Position = vpos; \n\
}";
static const char* VertexShaderSource = R"(
#version 140
#define pp_Gouraud %d
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#endif
/* Vertex constants*/
uniform highp vec4 scale;
uniform highp mat4 normal_matrix;
/* Vertex input */
in highp vec4 in_pos;
in lowp vec4 in_base;
in lowp vec4 in_offs;
in mediump vec2 in_uv;
in lowp vec4 in_base1;
in lowp vec4 in_offs1;
in mediump vec2 in_uv1;
/* output */
INTERPOLATION out lowp vec4 vtx_base;
INTERPOLATION out lowp vec4 vtx_offs;
out mediump vec2 vtx_uv;
INTERPOLATION out lowp vec4 vtx_base1;
INTERPOLATION out lowp vec4 vtx_offs1;
out mediump vec2 vtx_uv1;
void main()
{
vtx_base = in_base;
vtx_offs = in_offs;
vtx_uv = in_uv;
vtx_base1 = in_base1;
vtx_offs1 = in_offs1;
vtx_uv1 = in_uv1;
vec4 vpos = in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos = normal_matrix * vpos;
vpos.w = 1.0 / vpos.z;
vpos.z = vpos.w;
vpos.xy *= vpos.w;
gl_Position = vpos;
}
)";
const char* gl4PixelPipelineShader = SHADER_HEADER
"\
#define cp_AlphaTest %d \n\
#define pp_ClipTestMode %d \n\
#define pp_UseAlpha %d \n\
#define pp_Texture %d \n\
#define pp_IgnoreTexA %d \n\
#define pp_ShadInstr %d \n\
#define pp_Offset %d \n\
#define pp_FogCtrl %d \n\
#define pp_TwoVolumes %d \n\
#define pp_DepthFunc %d \n\
#define pp_Gouraud %d \n\
#define pp_BumpMap %d \n\
#define FogClamping %d \n\
#define PASS %d \n\
#define PI 3.1415926 \n\
\n\
#if PASS <= 1 \n\
out vec4 FragColor; \n\
#endif \n\
\n\
#if pp_TwoVolumes == 1 \n\
#define IF(x) if (x) \n\
#else \n\
#define IF(x) \n\
#endif \n\
\n\
#if pp_Gouraud == 0 \n\
#define INTERPOLATION flat \n\
#else \n\
#define INTERPOLATION smooth \n\
#endif \n\
\n\
/* Shader program params*/ \n\
uniform lowp float cp_AlphaTestValue; \n\
uniform lowp vec4 pp_ClipTest; \n\
uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT; \n\
uniform highp float sp_FOG_DENSITY; \n\
uniform highp float shade_scale_factor; \n\
uniform sampler2D tex0, tex1; \n\
layout(binding = 5) uniform sampler2D fog_table; \n\
uniform int pp_Number; \n\
uniform usampler2D shadow_stencil; \n\
uniform sampler2D DepthTex; \n\
uniform lowp float trilinear_alpha; \n\
uniform lowp vec4 fog_clamp_min; \n\
uniform lowp vec4 fog_clamp_max; \n\
\n\
uniform ivec2 blend_mode[2]; \n\
#if pp_TwoVolumes == 1 \n\
uniform bool use_alpha[2]; \n\
uniform bool ignore_tex_alpha[2]; \n\
uniform int shading_instr[2]; \n\
uniform int fog_control[2]; \n\
#endif \n\
\n\
uniform highp float extra_depth_scale; \n\
/* Vertex input*/ \n\
INTERPOLATION in lowp vec4 vtx_base; \n\
INTERPOLATION in lowp vec4 vtx_offs; \n\
in mediump vec2 vtx_uv; \n\
INTERPOLATION in lowp vec4 vtx_base1; \n\
INTERPOLATION in lowp vec4 vtx_offs1; \n\
in mediump vec2 vtx_uv1; \n\
\n\
lowp float fog_mode2(highp float w) \n\
{ \n\
highp float z = clamp(w * extra_depth_scale * sp_FOG_DENSITY, 1.0, 255.9999); \n\
highp float exp = floor(log2(z)); \n\
highp float m = z * 16.0 / pow(2.0, exp) - 16.0; \n\
float idx = floor(m) + exp * 16.0 + 0.5; \n\
vec4 fog_coef = texture(fog_table, vec2(idx / 128.0, 0.75 - (m - floor(m)) / 2.0)); \n\
return fog_coef.r; \n\
} \n\
\n\
highp vec4 fog_clamp(highp vec4 col) \n\
{ \n\
#if FogClamping == 1 \n\
return clamp(col, fog_clamp_min, fog_clamp_max); \n\
#else \n\
return col; \n\
#endif \n\
} \n\
\n\
void main() \n\
{ \n\
setFragDepth(); \n\
\n\
#if PASS == 3 \n\
// Manual depth testing \n\
highp float frontDepth = texture(DepthTex, gl_FragCoord.xy / textureSize(DepthTex, 0)).r; \n\
#if pp_DepthFunc == 0 // Never \n\
discard; \n\
#elif pp_DepthFunc == 1 // Less \n\
if (gl_FragDepth >= frontDepth) \n\
discard; \n\
#elif pp_DepthFunc == 2 // Equal \n\
if (gl_FragDepth != frontDepth) \n\
discard; \n\
#elif pp_DepthFunc == 3 // Less or equal \n\
if (gl_FragDepth > frontDepth) \n\
discard; \n\
#elif pp_DepthFunc == 4 // Greater \n\
if (gl_FragDepth <= frontDepth) \n\
discard; \n\
#elif pp_DepthFunc == 5 // Not equal \n\
if (gl_FragDepth == frontDepth) \n\
discard; \n\
#elif pp_DepthFunc == 6 // Greater or equal \n\
if (gl_FragDepth < frontDepth) \n\
discard; \n\
#endif \n\
#endif \n\
\n\
// Clip outside the box \n\
#if pp_ClipTestMode==1 \n\
if (gl_FragCoord.x < pp_ClipTest.x || gl_FragCoord.x > pp_ClipTest.z \n\
|| gl_FragCoord.y < pp_ClipTest.y || gl_FragCoord.y > pp_ClipTest.w) \n\
discard; \n\
#endif \n\
// Clip inside the box \n\
#if pp_ClipTestMode==-1 \n\
if (gl_FragCoord.x >= pp_ClipTest.x && gl_FragCoord.x <= pp_ClipTest.z \n\
&& gl_FragCoord.y >= pp_ClipTest.y && gl_FragCoord.y <= pp_ClipTest.w) \n\
discard; \n\
#endif \n\
\n\
highp vec4 color = vtx_base; \n\
lowp vec4 offset = vtx_offs; \n\
mediump vec2 uv = vtx_uv; \n\
bool area1 = false; \n\
ivec2 cur_blend_mode = blend_mode[0]; \n\
\n\
#if pp_TwoVolumes == 1 \n\
bool cur_use_alpha = use_alpha[0]; \n\
bool cur_ignore_tex_alpha = ignore_tex_alpha[0]; \n\
int cur_shading_instr = shading_instr[0]; \n\
int cur_fog_control = fog_control[0]; \n\
#if PASS == 1 \n\
uvec4 stencil = texture(shadow_stencil, gl_FragCoord.xy / textureSize(shadow_stencil, 0)); \n\
if (stencil.r == 0x81u) { \n\
color = vtx_base1; \n\
offset = vtx_offs1; \n\
uv = vtx_uv1; \n\
area1 = true; \n\
cur_blend_mode = blend_mode[1]; \n\
cur_use_alpha = use_alpha[1]; \n\
cur_ignore_tex_alpha = ignore_tex_alpha[1]; \n\
cur_shading_instr = shading_instr[1]; \n\
cur_fog_control = fog_control[1]; \n\
} \n\
#endif\n\
#endif\n\
\n\
#if pp_UseAlpha==0 || pp_TwoVolumes == 1 \n\
IF(!cur_use_alpha) \n\
color.a=1.0; \n\
#endif\n\
#if pp_FogCtrl==3 || pp_TwoVolumes == 1 // LUT Mode 2 \n\
IF(cur_fog_control == 3) \n\
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\
#endif\n\
#if pp_Texture==1 \n\
{ \n\
highp vec4 texcol; \n\
if (area1) \n\
texcol = texture(tex1, uv); \n\
else \n\
texcol = texture(tex0, uv); \n\
#if pp_BumpMap == 1 \n\
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0; \n\
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0; \n\
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0); \n\
texcol.rgb = vec3(1.0, 1.0, 1.0); \n\
#else\n\
#if pp_IgnoreTexA==1 || pp_TwoVolumes == 1 \n\
IF(cur_ignore_tex_alpha) \n\
texcol.a=1.0; \n\
#endif\n\
\n\
#if cp_AlphaTest == 1 \n\
if (cp_AlphaTestValue>texcol.a) discard;\n\
#endif \n\
#endif\n\
#if pp_ShadInstr==0 || pp_TwoVolumes == 1 // DECAL \n\
IF(cur_shading_instr == 0) \n\
{ \n\
color=texcol; \n\
} \n\
#endif\n\
#if pp_ShadInstr==1 || pp_TwoVolumes == 1 // MODULATE \n\
IF(cur_shading_instr == 1) \n\
{ \n\
color.rgb*=texcol.rgb; \n\
color.a=texcol.a; \n\
} \n\
#endif\n\
#if pp_ShadInstr==2 || pp_TwoVolumes == 1 // DECAL ALPHA \n\
IF(cur_shading_instr == 2) \n\
{ \n\
color.rgb=mix(color.rgb,texcol.rgb,texcol.a); \n\
} \n\
#endif\n\
#if pp_ShadInstr==3 || pp_TwoVolumes == 1 // MODULATE ALPHA \n\
IF(cur_shading_instr == 3) \n\
{ \n\
color*=texcol; \n\
} \n\
#endif\n\
\n\
#if pp_Offset==1 && pp_BumpMap == 0 \n\
{ \n\
color.rgb += offset.rgb; \n\
} \n\
#endif\n\
} \n\
#endif\n\
#if PASS == 1 && pp_TwoVolumes == 0 \n\
uvec4 stencil = texture(shadow_stencil, gl_FragCoord.xy / textureSize(shadow_stencil, 0)); \n\
if (stencil.r == 0x81u) \n\
color.rgb *= shade_scale_factor; \n\
#endif \n\
\n\
color = fog_clamp(color); \n\
\n\
#if pp_FogCtrl==0 || pp_TwoVolumes == 1 // LUT \n\
IF(cur_fog_control == 0) \n\
{ \n\
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\
} \n\
#endif\n\
#if pp_Offset==1 && pp_BumpMap == 0 && (pp_FogCtrl == 1 || pp_TwoVolumes == 1) // Per vertex \n\
IF(cur_fog_control == 1) \n\
{ \n\
color.rgb=mix(color.rgb, sp_FOG_COL_VERT.rgb, offset.a); \n\
} \n\
#endif\n\
\n\
color *= trilinear_alpha; \n\
\n\
#if cp_AlphaTest == 1 \n\
color.a=1.0; \n\
#endif \n\
\n\
//color.rgb=vec3(gl_FragCoord.w * sp_FOG_DENSITY / 128.0); \n\
\n\
#if PASS == 1 \n\
FragColor = color; \n\
#elif PASS > 1 \n\
// Discard as many pixels as possible \n\
switch (cur_blend_mode.y) // DST \n\
{ \n\
case ONE: \n\
switch (cur_blend_mode.x) // SRC \n\
{ \n\
case ZERO: \n\
discard; \n\
case ONE: \n\
case OTHER_COLOR: \n\
case INVERSE_OTHER_COLOR: \n\
if (color == vec4(0.0)) \n\
discard; \n\
break; \n\
case SRC_ALPHA: \n\
if (color.a == 0.0 || color.rgb == vec3(0.0)) \n\
discard; \n\
break; \n\
case INVERSE_SRC_ALPHA: \n\
if (color.a == 1.0 || color.rgb == vec3(0.0)) \n\
discard; \n\
break; \n\
} \n\
break; \n\
case OTHER_COLOR: \n\
if (cur_blend_mode.x == ZERO && color == vec4(1.0)) \n\
discard; \n\
break; \n\
case INVERSE_OTHER_COLOR: \n\
if (cur_blend_mode.x <= SRC_ALPHA && color == vec4(0.0)) \n\
discard; \n\
break; \n\
case SRC_ALPHA: \n\
if ((cur_blend_mode.x == ZERO || cur_blend_mode.x == INVERSE_SRC_ALPHA) && color.a == 1.0) \n\
discard; \n\
break; \n\
case INVERSE_SRC_ALPHA: \n\
switch (cur_blend_mode.x) // SRC \n\
{ \n\
case ZERO: \n\
case SRC_ALPHA: \n\
if (color.a == 0.0) \n\
discard; \n\
break; \n\
case ONE: \n\
case OTHER_COLOR: \n\
case INVERSE_OTHER_COLOR: \n\
if (color == vec4(0.0)) \n\
discard; \n\
break; \n\
} \n\
break; \n\
} \n\
\n\
ivec2 coords = ivec2(gl_FragCoord.xy); \n\
uint idx = getNextPixelIndex(); \n\
\n\
Pixel pixel; \n\
pixel.color = color; \n\
pixel.depth = gl_FragDepth; \n\
pixel.seq_num = uint(pp_Number); \n\
pixel.next = imageAtomicExchange(abufferPointerImg, coords, idx); \n\
pixels[idx] = pixel; \n\
\n\
discard; \n\
\n\
#endif \n\
}";
R"(
#define cp_AlphaTest %d
#define pp_ClipTestMode %d
#define pp_UseAlpha %d
#define pp_Texture %d
#define pp_IgnoreTexA %d
#define pp_ShadInstr %d
#define pp_Offset %d
#define pp_FogCtrl %d
#define pp_TwoVolumes %d
#define pp_DepthFunc %d
#define pp_Gouraud %d
#define pp_BumpMap %d
#define FogClamping %d
#define PASS %d
#define PI 3.1415926
#if PASS <= 1
out vec4 FragColor;
#endif
#if pp_TwoVolumes == 1
#define IF(x) if (x)
#else
#define IF(x)
#endif
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#endif
/* Shader program params*/
uniform lowp float cp_AlphaTestValue;
uniform lowp vec4 pp_ClipTest;
uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT;
uniform highp float sp_FOG_DENSITY;
uniform highp float shade_scale_factor;
uniform sampler2D tex0, tex1;
layout(binding = 5) uniform sampler2D fog_table;
uniform int pp_Number;
uniform usampler2D shadow_stencil;
uniform sampler2D DepthTex;
uniform lowp float trilinear_alpha;
uniform lowp vec4 fog_clamp_min;
uniform lowp vec4 fog_clamp_max;
uniform ivec2 blend_mode[2];
#if pp_TwoVolumes == 1
uniform bool use_alpha[2];
uniform bool ignore_tex_alpha[2];
uniform int shading_instr[2];
uniform int fog_control[2];
#endif
uniform highp float extra_depth_scale;
/* Vertex input*/
INTERPOLATION in lowp vec4 vtx_base;
INTERPOLATION in lowp vec4 vtx_offs;
in mediump vec2 vtx_uv;
INTERPOLATION in lowp vec4 vtx_base1;
INTERPOLATION in lowp vec4 vtx_offs1;
in mediump vec2 vtx_uv1;
lowp float fog_mode2(highp float w)
{
highp float z = clamp(w * extra_depth_scale * sp_FOG_DENSITY, 1.0, 255.9999);
highp float exp = floor(log2(z));
highp float m = z * 16.0 / pow(2.0, exp) - 16.0;
float idx = floor(m) + exp * 16.0 + 0.5;
vec4 fog_coef = texture(fog_table, vec2(idx / 128.0, 0.75 - (m - floor(m)) / 2.0));
return fog_coef.r;
}
highp vec4 fog_clamp(highp vec4 col)
{
#if FogClamping == 1
return clamp(col, fog_clamp_min, fog_clamp_max);
#else
return col;
#endif
}
void main()
{
setFragDepth();
#if PASS == 3
// Manual depth testing
highp float frontDepth = texture(DepthTex, gl_FragCoord.xy / textureSize(DepthTex, 0)).r;
#if pp_DepthFunc == 0 // Never
discard;
#elif pp_DepthFunc == 1 // Less
if (gl_FragDepth >= frontDepth)
discard;
#elif pp_DepthFunc == 2 // Equal
if (gl_FragDepth != frontDepth)
discard;
#elif pp_DepthFunc == 3 // Less or equal
if (gl_FragDepth > frontDepth)
discard;
#elif pp_DepthFunc == 4 // Greater
if (gl_FragDepth <= frontDepth)
discard;
#elif pp_DepthFunc == 5 // Not equal
if (gl_FragDepth == frontDepth)
discard;
#elif pp_DepthFunc == 6 // Greater or equal
if (gl_FragDepth < frontDepth)
discard;
#endif
#endif
// Clip outside the box
#if pp_ClipTestMode==1
if (gl_FragCoord.x < pp_ClipTest.x || gl_FragCoord.x > pp_ClipTest.z
|| gl_FragCoord.y < pp_ClipTest.y || gl_FragCoord.y > pp_ClipTest.w)
discard;
#endif
// Clip inside the box
#if pp_ClipTestMode==-1
if (gl_FragCoord.x >= pp_ClipTest.x && gl_FragCoord.x <= pp_ClipTest.z
&& gl_FragCoord.y >= pp_ClipTest.y && gl_FragCoord.y <= pp_ClipTest.w)
discard;
#endif
highp vec4 color = vtx_base;
lowp vec4 offset = vtx_offs;
mediump vec2 uv = vtx_uv;
bool area1 = false;
ivec2 cur_blend_mode = blend_mode[0];
#if pp_TwoVolumes == 1
bool cur_use_alpha = use_alpha[0];
bool cur_ignore_tex_alpha = ignore_tex_alpha[0];
int cur_shading_instr = shading_instr[0];
int cur_fog_control = fog_control[0];
#if PASS == 1
uvec4 stencil = texture(shadow_stencil, gl_FragCoord.xy / textureSize(shadow_stencil, 0));
if (stencil.r == 0x81u) {
color = vtx_base1;
offset = vtx_offs1;
uv = vtx_uv1;
area1 = true;
cur_blend_mode = blend_mode[1];
cur_use_alpha = use_alpha[1];
cur_ignore_tex_alpha = ignore_tex_alpha[1];
cur_shading_instr = shading_instr[1];
cur_fog_control = fog_control[1];
}
#endif
#endif
#if pp_UseAlpha==0 || pp_TwoVolumes == 1
IF(!cur_use_alpha)
color.a=1.0;
#endif
#if pp_FogCtrl==3 || pp_TwoVolumes == 1 // LUT Mode 2
IF(cur_fog_control == 3)
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
#endif
#if pp_Texture==1
{
highp vec4 texcol;
if (area1)
texcol = texture(tex1, uv);
else
texcol = texture(tex0, uv);
#if pp_BumpMap == 1
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA==1 || pp_TwoVolumes == 1
IF(cur_ignore_tex_alpha)
texcol.a=1.0;
#endif
#if cp_AlphaTest == 1
if (cp_AlphaTestValue>texcol.a) discard;
#endif
#endif
#if pp_ShadInstr==0 || pp_TwoVolumes == 1 // DECAL
IF(cur_shading_instr == 0)
{
color=texcol;
}
#endif
#if pp_ShadInstr==1 || pp_TwoVolumes == 1 // MODULATE
IF(cur_shading_instr == 1)
{
color.rgb*=texcol.rgb;
color.a=texcol.a;
}
#endif
#if pp_ShadInstr==2 || pp_TwoVolumes == 1 // DECAL ALPHA
IF(cur_shading_instr == 2)
{
color.rgb=mix(color.rgb,texcol.rgb,texcol.a);
}
#endif
#if pp_ShadInstr==3 || pp_TwoVolumes == 1 // MODULATE ALPHA
IF(cur_shading_instr == 3)
{
color*=texcol;
}
#endif
#if pp_Offset==1 && pp_BumpMap == 0
{
color.rgb += offset.rgb;
}
#endif
}
#endif
#if PASS == 1 && pp_TwoVolumes == 0
uvec4 stencil = texture(shadow_stencil, gl_FragCoord.xy / textureSize(shadow_stencil, 0));
if (stencil.r == 0x81u)
color.rgb *= shade_scale_factor;
#endif
color = fog_clamp(color);
#if pp_FogCtrl==0 || pp_TwoVolumes == 1 // LUT
IF(cur_fog_control == 0)
{
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
}
#endif
#if pp_Offset==1 && pp_BumpMap == 0 && (pp_FogCtrl == 1 || pp_TwoVolumes == 1) // Per vertex
IF(cur_fog_control == 1)
{
color.rgb=mix(color.rgb, sp_FOG_COL_VERT.rgb, offset.a);
}
#endif
color *= trilinear_alpha;
#if cp_AlphaTest == 1
color.a=1.0;
#endif
//color.rgb=vec3(gl_FragCoord.w * sp_FOG_DENSITY / 128.0);
#if PASS == 1
FragColor = color;
#elif PASS > 1
// Discard as many pixels as possible
switch (cur_blend_mode.y) // DST
{
case ONE:
switch (cur_blend_mode.x) // SRC
{
case ZERO:
discard;
case ONE:
case OTHER_COLOR:
case INVERSE_OTHER_COLOR:
if (color == vec4(0.0))
discard;
break;
case SRC_ALPHA:
if (color.a == 0.0 || color.rgb == vec3(0.0))
discard;
break;
case INVERSE_SRC_ALPHA:
if (color.a == 1.0 || color.rgb == vec3(0.0))
discard;
break;
}
break;
case OTHER_COLOR:
if (cur_blend_mode.x == ZERO && color == vec4(1.0))
discard;
break;
case INVERSE_OTHER_COLOR:
if (cur_blend_mode.x <= SRC_ALPHA && color == vec4(0.0))
discard;
break;
case SRC_ALPHA:
if ((cur_blend_mode.x == ZERO || cur_blend_mode.x == INVERSE_SRC_ALPHA) && color.a == 1.0)
discard;
break;
case INVERSE_SRC_ALPHA:
switch (cur_blend_mode.x) // SRC
{
case ZERO:
case SRC_ALPHA:
if (color.a == 0.0)
discard;
break;
case ONE:
case OTHER_COLOR:
case INVERSE_OTHER_COLOR:
if (color == vec4(0.0))
discard;
break;
}
break;
}
ivec2 coords = ivec2(gl_FragCoord.xy);
uint idx = getNextPixelIndex();
Pixel pixel;
pixel.color = color;
pixel.depth = gl_FragDepth;
pixel.seq_num = uint(pp_Number);
pixel.next = imageAtomicExchange(abufferPointerImg, coords, idx);
pixels[idx] = pixel;
discard;
#endif
}
)";
static const char* ModifierVolumeShader = SHADER_HEADER
" \
/* Vertex input*/ \n\
void main() \n\
{ \n\
setFragDepth(); \n\
\n\
}";
R"(
void main()
{
setFragDepth();
}
)";
gl4_ctx gl4;

View File

@ -25,365 +25,369 @@
float fb_scale_x, fb_scale_y; // FIXME
//Fragment and vertex shaders code
const char* VertexShaderSource =
"\
%s \n\
#define TARGET_GL %s \n\
#define pp_Gouraud %d \n\
\n\
#define GLES2 0 \n\
#define GLES3 1 \n\
#define GL2 2 \n\
#define GL3 3 \n\
\n\
#if TARGET_GL == GL2 \n\
#define highp \n\
#define lowp \n\
#define mediump \n\
#endif \n\
#if TARGET_GL == GLES2 || TARGET_GL == GL2 \n\
#define in attribute \n\
#define out varying \n\
#endif \n\
\n\
\n\
#if TARGET_GL == GL3 || TARGET_GL == GLES3 \n\
#if pp_Gouraud == 0 \n\
#define INTERPOLATION flat \n\
#else \n\
#define INTERPOLATION smooth \n\
#endif \n\
#else \n\
#define INTERPOLATION \n\
#endif \n\
\n\
/* Vertex constants*/ \n\
uniform highp vec4 scale; \n\
uniform highp vec4 depth_scale; \n\
uniform highp mat4 normal_matrix; \n\
/* Vertex input */ \n\
in highp vec4 in_pos; \n\
in lowp vec4 in_base; \n\
in lowp vec4 in_offs; \n\
in mediump vec2 in_uv; \n\
/* output */ \n\
INTERPOLATION out lowp vec4 vtx_base; \n\
INTERPOLATION out lowp vec4 vtx_offs; \n\
out mediump vec2 vtx_uv; \n\
void main() \n\
{ \n\
vtx_base = in_base; \n\
vtx_offs = in_offs; \n\
vtx_uv = in_uv; \n\
highp vec4 vpos = in_pos; \n\
if (vpos.z < 0.0 || vpos.z > 3.4e37) \n\
{ \n\
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z); \n\
return; \n\
} \n\
\n\
vpos = normal_matrix * vpos; \n\
vpos.w = 1.0 / vpos.z; \n\
#if TARGET_GL != GLES2 \n\
vpos.z = vpos.w; \n\
#else \n\
vpos.z = depth_scale.x + depth_scale.y * vpos.w; \n\
#endif \n\
vpos.xy *= vpos.w; \n\
gl_Position = vpos; \n\
}";
const char* VertexShaderSource = R"(
%s
#define TARGET_GL %s
#define pp_Gouraud %d
#define GLES2 0
#define GLES3 1
#define GL2 2
#define GL3 3
#if TARGET_GL == GL2
#define highp
#define lowp
#define mediump
#endif
#if TARGET_GL == GLES2 || TARGET_GL == GL2
#define in attribute
#define out varying
#endif
#if TARGET_GL == GL3 || TARGET_GL == GLES3
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#endif
#else
#define INTERPOLATION
#endif
/* Vertex constants*/
uniform highp vec4 scale;
uniform highp vec4 depth_scale;
uniform highp mat4 normal_matrix;
/* Vertex input */
in highp vec4 in_pos;
in lowp vec4 in_base;
in lowp vec4 in_offs;
in mediump vec2 in_uv;
/* output */
INTERPOLATION out lowp vec4 vtx_base;
INTERPOLATION out lowp vec4 vtx_offs;
out mediump vec2 vtx_uv;
void main()
{
vtx_base = in_base;
vtx_offs = in_offs;
vtx_uv = in_uv;
highp vec4 vpos = in_pos;
if (vpos.z < 0.0 || vpos.z > 3.4e37)
{
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
return;
}
vpos = normal_matrix * vpos;
vpos.w = 1.0 / vpos.z;
#if TARGET_GL != GLES2
vpos.z = vpos.w;
#else
vpos.z = depth_scale.x + depth_scale.y * vpos.w;
#endif
vpos.xy *= vpos.w;
gl_Position = vpos;
}
)";
const char* PixelPipelineShader =
"\
%s \n\
#define TARGET_GL %s \n\
\n\
#define cp_AlphaTest %d \n\
#define pp_ClipTestMode %d \n\
#define pp_UseAlpha %d \n\
#define pp_Texture %d \n\
#define pp_IgnoreTexA %d \n\
#define pp_ShadInstr %d \n\
#define pp_Offset %d \n\
#define pp_FogCtrl %d \n\
#define pp_Gouraud %d \n\
#define pp_BumpMap %d \n\
#define FogClamping %d \n\
#define pp_TriLinear %d \n\
#define PI 3.1415926 \n\
\n\
#define GLES2 0 \n\
#define GLES3 1 \n\
#define GL2 2 \n\
#define GL3 3 \n\
\n\
#if TARGET_GL == GL2 \n\
#define highp \n\
#define lowp \n\
#define mediump \n\
#endif \n\
#if TARGET_GL == GLES3 \n\
out highp vec4 FragColor; \n\
#define gl_FragColor FragColor \n\
#define FOG_CHANNEL a \n\
#elif TARGET_GL == GL3 \n\
out highp vec4 FragColor; \n\
#define gl_FragColor FragColor \n\
#define FOG_CHANNEL r \n\
#else \n\
#define in varying \n\
#define texture texture2D \n\
#define FOG_CHANNEL a \n\
#endif \n\
\n\
\n\
#if TARGET_GL == GL3 || TARGET_GL == GLES3 \n\
#if pp_Gouraud == 0 \n\
#define INTERPOLATION flat \n\
#else \n\
#define INTERPOLATION smooth \n\
#endif \n\
#else \n\
#define INTERPOLATION \n\
#endif \n\
\n\
/* Shader program params*/ \n\
/* gles has no alpha test stage, so its emulated on the shader */ \n\
uniform lowp float cp_AlphaTestValue; \n\
uniform lowp vec4 pp_ClipTest; \n\
uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT; \n\
uniform highp float sp_FOG_DENSITY; \n\
uniform sampler2D tex,fog_table; \n\
uniform lowp float trilinear_alpha; \n\
uniform lowp vec4 fog_clamp_min; \n\
uniform lowp vec4 fog_clamp_max; \n\
uniform highp float extra_depth_scale; \n\
/* Vertex input*/ \n\
INTERPOLATION in lowp vec4 vtx_base; \n\
INTERPOLATION in lowp vec4 vtx_offs; \n\
in mediump vec2 vtx_uv; \n\
\n\
lowp float fog_mode2(highp float w) \n\
{ \n\
highp float z = clamp(w * extra_depth_scale * sp_FOG_DENSITY, 1.0, 255.9999); \n\
highp float exp = floor(log2(z)); \n\
highp float m = z * 16.0 / pow(2.0, exp) - 16.0; \n\
lowp float idx = floor(m) + exp * 16.0 + 0.5; \n\
highp vec4 fog_coef = texture(fog_table, vec2(idx / 128.0, 0.75 - (m - floor(m)) / 2.0)); \n\
return fog_coef.FOG_CHANNEL; \n\
} \n\
\n\
highp vec4 fog_clamp(lowp vec4 col) \n\
{ \n\
#if FogClamping == 1 \n\
return clamp(col, fog_clamp_min, fog_clamp_max); \n\
#else \n\
return col; \n\
#endif \n\
} \n\
\n\
void main() \n\
{ \n\
// Clip outside the box \n\
#if pp_ClipTestMode==1 \n\
if (gl_FragCoord.x < pp_ClipTest.x || gl_FragCoord.x > pp_ClipTest.z \n\
|| gl_FragCoord.y < pp_ClipTest.y || gl_FragCoord.y > pp_ClipTest.w) \n\
discard; \n\
#endif \n\
// Clip inside the box \n\
#if pp_ClipTestMode==-1 \n\
if (gl_FragCoord.x >= pp_ClipTest.x && gl_FragCoord.x <= pp_ClipTest.z \n\
&& gl_FragCoord.y >= pp_ClipTest.y && gl_FragCoord.y <= pp_ClipTest.w) \n\
discard; \n\
#endif \n\
\n\
lowp vec4 color=vtx_base; \n\
#if pp_UseAlpha==0 \n\
color.a=1.0; \n\
#endif\n\
#if pp_FogCtrl==3 \n\
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\
#endif\n\
#if pp_Texture==1 \n\
{ \n\
lowp vec4 texcol=texture(tex, vtx_uv); \n\
\n\
#if pp_BumpMap == 1 \n\
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0; \n\
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0; \n\
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0); \n\
texcol.rgb = vec3(1.0, 1.0, 1.0); \n\
#else\n\
#if pp_IgnoreTexA==1 \n\
texcol.a=1.0; \n\
#endif\n\
\n\
#if cp_AlphaTest == 1 \n\
if (cp_AlphaTestValue > texcol.a) \n\
discard; \n\
#endif \n\
#endif \n\
#if pp_ShadInstr==0 \n\
{ \n\
color=texcol; \n\
} \n\
#endif\n\
#if pp_ShadInstr==1 \n\
{ \n\
color.rgb*=texcol.rgb; \n\
color.a=texcol.a; \n\
} \n\
#endif\n\
#if pp_ShadInstr==2 \n\
{ \n\
color.rgb=mix(color.rgb,texcol.rgb,texcol.a); \n\
} \n\
#endif\n\
#if pp_ShadInstr==3 \n\
{ \n\
color*=texcol; \n\
} \n\
#endif\n\
\n\
#if pp_Offset==1 && pp_BumpMap == 0 \n\
{ \n\
color.rgb+=vtx_offs.rgb; \n\
} \n\
#endif\n\
} \n\
#endif\n\
\n\
color = fog_clamp(color); \n\
\n\
#if pp_FogCtrl == 0 \n\
{ \n\
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\
} \n\
#endif\n\
#if pp_FogCtrl == 1 && pp_Offset==1 && pp_BumpMap == 0 \n\
{ \n\
color.rgb=mix(color.rgb,sp_FOG_COL_VERT.rgb,vtx_offs.a); \n\
} \n\
#endif\n\
\n\
#if pp_TriLinear == 1 \n\
color *= trilinear_alpha; \n\
#endif \n\
\n\
#if cp_AlphaTest == 1 \n\
color.a=1.0; \n\
#endif \n\
//color.rgb=vec3(gl_FragCoord.w * sp_FOG_DENSITY / 128.0);\n\
#if TARGET_GL != GLES2 \n\
highp float w = gl_FragCoord.w * 100000.0; \n\
gl_FragDepth = log2(1.0 + w) / 34.0; \n\
#endif \n\
gl_FragColor =color; \n\
}";
R"(
%s
#define TARGET_GL %s
#define cp_AlphaTest %d
#define pp_ClipTestMode %d
#define pp_UseAlpha %d
#define pp_Texture %d
#define pp_IgnoreTexA %d
#define pp_ShadInstr %d
#define pp_Offset %d
#define pp_FogCtrl %d
#define pp_Gouraud %d
#define pp_BumpMap %d
#define FogClamping %d
#define pp_TriLinear %d
#define PI 3.1415926
#define GLES2 0
#define GLES3 1
#define GL2 2
#define GL3 3
#if TARGET_GL == GL2
#define highp
#define lowp
#define mediump
#endif
#if TARGET_GL == GLES3
out highp vec4 FragColor;
#define gl_FragColor FragColor
#define FOG_CHANNEL a
#elif TARGET_GL == GL3
out highp vec4 FragColor;
#define gl_FragColor FragColor
#define FOG_CHANNEL r
#else
#define in varying
#define texture texture2D
#define FOG_CHANNEL a
#endif
#if TARGET_GL == GL3 || TARGET_GL == GLES3
#if pp_Gouraud == 0
#define INTERPOLATION flat
#else
#define INTERPOLATION smooth
#endif
#else
#define INTERPOLATION
#endif
/* Shader program params*/
/* gles has no alpha test stage, so its emulated on the shader */
uniform lowp float cp_AlphaTestValue;
uniform lowp vec4 pp_ClipTest;
uniform lowp vec3 sp_FOG_COL_RAM,sp_FOG_COL_VERT;
uniform highp float sp_FOG_DENSITY;
uniform sampler2D tex,fog_table;
uniform lowp float trilinear_alpha;
uniform lowp vec4 fog_clamp_min;
uniform lowp vec4 fog_clamp_max;
uniform highp float extra_depth_scale;
/* Vertex input*/
INTERPOLATION in lowp vec4 vtx_base;
INTERPOLATION in lowp vec4 vtx_offs;
in mediump vec2 vtx_uv;
lowp float fog_mode2(highp float w)
{
highp float z = clamp(w * extra_depth_scale * sp_FOG_DENSITY, 1.0, 255.9999);
highp float exp = floor(log2(z));
highp float m = z * 16.0 / pow(2.0, exp) - 16.0;
lowp float idx = floor(m) + exp * 16.0 + 0.5;
highp vec4 fog_coef = texture(fog_table, vec2(idx / 128.0, 0.75 - (m - floor(m)) / 2.0));
return fog_coef.FOG_CHANNEL;
}
highp vec4 fog_clamp(lowp vec4 col)
{
#if FogClamping == 1
return clamp(col, fog_clamp_min, fog_clamp_max);
#else
return col;
#endif
}
void main()
{
// Clip outside the box
#if pp_ClipTestMode==1
if (gl_FragCoord.x < pp_ClipTest.x || gl_FragCoord.x > pp_ClipTest.z
|| gl_FragCoord.y < pp_ClipTest.y || gl_FragCoord.y > pp_ClipTest.w)
discard;
#endif
// Clip inside the box
#if pp_ClipTestMode==-1
if (gl_FragCoord.x >= pp_ClipTest.x && gl_FragCoord.x <= pp_ClipTest.z
&& gl_FragCoord.y >= pp_ClipTest.y && gl_FragCoord.y <= pp_ClipTest.w)
discard;
#endif
lowp vec4 color=vtx_base;
#if pp_UseAlpha==0
color.a=1.0;
#endif
#if pp_FogCtrl==3
color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
#endif
#if pp_Texture==1
{
lowp vec4 texcol=texture(tex, vtx_uv);
#if pp_BumpMap == 1
highp float s = PI / 2.0 * (texcol.a * 15.0 * 16.0 + texcol.r * 15.0) / 255.0;
highp float r = 2.0 * PI * (texcol.g * 15.0 * 16.0 + texcol.b * 15.0) / 255.0;
texcol.a = clamp(vtx_offs.a + vtx_offs.r * sin(s) + vtx_offs.g * cos(s) * cos(r - 2.0 * PI * vtx_offs.b), 0.0, 1.0);
texcol.rgb = vec3(1.0, 1.0, 1.0);
#else
#if pp_IgnoreTexA==1
texcol.a=1.0;
#endif
#if cp_AlphaTest == 1
if (cp_AlphaTestValue > texcol.a)
discard;
#endif
#endif
#if pp_ShadInstr==0
{
color=texcol;
}
#endif
#if pp_ShadInstr==1
{
color.rgb*=texcol.rgb;
color.a=texcol.a;
}
#endif
#if pp_ShadInstr==2
{
color.rgb=mix(color.rgb,texcol.rgb,texcol.a);
}
#endif
#if pp_ShadInstr==3
{
color*=texcol;
}
#endif
#if pp_Offset==1 && pp_BumpMap == 0
{
color.rgb+=vtx_offs.rgb;
}
#endif
}
#endif
color = fog_clamp(color);
#if pp_FogCtrl == 0
{
color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w));
}
#endif
#if pp_FogCtrl == 1 && pp_Offset==1 && pp_BumpMap == 0
{
color.rgb=mix(color.rgb,sp_FOG_COL_VERT.rgb,vtx_offs.a);
}
#endif
#if pp_TriLinear == 1
color *= trilinear_alpha;
#endif
#if cp_AlphaTest == 1
color.a=1.0;
#endif
//color.rgb=vec3(gl_FragCoord.w * sp_FOG_DENSITY / 128.0);
#if TARGET_GL != GLES2
highp float w = gl_FragCoord.w * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
#endif
gl_FragColor =color;
}
)";
const char* ModifierVolumeShader =
"\
%s \n\
#define TARGET_GL %s \n\
\n\
#define GLES2 0 \n\
#define GLES3 1 \n\
#define GL2 2 \n\
#define GL3 3 \n\
\n\
#if TARGET_GL == GL2 \n\
#define highp \n\
#define lowp \n\
#define mediump \n\
#endif \n\
#if TARGET_GL != GLES2 && TARGET_GL != GL2 \n\
out highp vec4 FragColor; \n\
#define gl_FragColor FragColor \n\
#endif \n\
\n\
uniform lowp float sp_ShaderColor; \n\
/* Vertex input*/ \n\
void main() \n\
{ \n\
#if TARGET_GL != GLES2 \n\
highp float w = gl_FragCoord.w * 100000.0; \n\
gl_FragDepth = log2(1.0 + w) / 34.0; \n\
#endif \n\
gl_FragColor=vec4(0.0, 0.0, 0.0, sp_ShaderColor); \n\
}";
R"(
%s
#define TARGET_GL %s
#define GLES2 0
#define GLES3 1
#define GL2 2
#define GL3 3
#if TARGET_GL == GL2
#define highp
#define lowp
#define mediump
#endif
#if TARGET_GL != GLES2 && TARGET_GL != GL2
out highp vec4 FragColor;
#define gl_FragColor FragColor
#endif
uniform lowp float sp_ShaderColor;
/* Vertex input*/
void main()
{
#if TARGET_GL != GLES2
highp float w = gl_FragCoord.w * 100000.0;
gl_FragDepth = log2(1.0 + w) / 34.0;
#endif
gl_FragColor=vec4(0.0, 0.0, 0.0, sp_ShaderColor);
}
)";
const char* OSD_VertexShader =
"\
%s \n\
#define TARGET_GL %s \n\
\n\
#define GLES2 0 \n\
#define GLES3 1 \n\
#define GL2 2 \n\
#define GL3 3 \n\
\n\
#if TARGET_GL == GL2 \n\
#define highp \n\
#define lowp \n\
#define mediump \n\
#endif \n\
#if TARGET_GL == GLES2 || TARGET_GL == GL2 \n\
#define in attribute \n\
#define out varying \n\
#endif \n\
\n\
uniform highp vec4 scale; \n\
\n\
in highp vec4 in_pos; \n\
in lowp vec4 in_base; \n\
in mediump vec2 in_uv; \n\
\n\
out lowp vec4 vtx_base; \n\
out mediump vec2 vtx_uv; \n\
\n\
void main() \n\
{ \n\
vtx_base = in_base; \n\
vtx_uv = in_uv; \n\
highp vec4 vpos = in_pos; \n\
\n\
vpos.w = 1.0; \n\
vpos.z = vpos.w; \n\
vpos.xy = vpos.xy * scale.xy - scale.zw; \n\
gl_Position = vpos; \n\
}";
R"(
%s
#define TARGET_GL %s
#define GLES2 0
#define GLES3 1
#define GL2 2
#define GL3 3
#if TARGET_GL == GL2
#define highp
#define lowp
#define mediump
#endif
#if TARGET_GL == GLES2 || TARGET_GL == GL2
#define in attribute
#define out varying
#endif
uniform highp vec4 scale;
in highp vec4 in_pos;
in lowp vec4 in_base;
in mediump vec2 in_uv;
out lowp vec4 vtx_base;
out mediump vec2 vtx_uv;
void main()
{
vtx_base = in_base;
vtx_uv = in_uv;
highp vec4 vpos = in_pos;
vpos.w = 1.0;
vpos.z = vpos.w;
vpos.xy = vpos.xy * scale.xy - scale.zw;
gl_Position = vpos;
}
)";
const char* OSD_Shader =
"\
%s \n\
#define TARGET_GL %s \n\
\n\
#define GLES2 0 \n\
#define GLES3 1 \n\
#define GL2 2 \n\
#define GL3 3 \n\
\n\
#if TARGET_GL == GL2 \n\
#define highp \n\
#define lowp \n\
#define mediump \n\
#endif \n\
#if TARGET_GL != GLES2 && TARGET_GL != GL2 \n\
out highp vec4 FragColor; \n\
#define gl_FragColor FragColor \n\
#else \n\
#define in varying \n\
#define texture texture2D \n\
#endif \n\
\n\
in lowp vec4 vtx_base; \n\
in mediump vec2 vtx_uv; \n\
\n\
uniform sampler2D tex; \n\
void main() \n\
{ \n\
gl_FragColor = vtx_base * texture(tex, vtx_uv); \n\
}";
R"(
%s
#define TARGET_GL %s
#define GLES2 0
#define GLES3 1
#define GL2 2
#define GL3 3
#if TARGET_GL == GL2
#define highp
#define lowp
#define mediump
#endif
#if TARGET_GL != GLES2 && TARGET_GL != GL2
out highp vec4 FragColor;
#define gl_FragColor FragColor
#else
#define in varying
#define texture texture2D
#endif
in lowp vec4 vtx_base;
in mediump vec2 vtx_uv;
uniform sampler2D tex;
void main()
{
gl_FragColor = vtx_base * texture(tex, vtx_uv);
}
)";
GLCache glcache;
gl_ctx gl;

View File

@ -642,8 +642,8 @@ static void gui_display_settings()
ImGui::NewFrame();
int dynarec_enabled = settings.dynarec.Enable;
int renderer = settings.pvr.rend;
bool vulkan = renderer == 4;
int pvr_rend = settings.pvr.rend;
bool vulkan = pvr_rend == 4;
if (!settings_opening && settings.pvr.IsOpenGL())
ImGui_ImplOpenGL3_DrawBackground();
@ -952,7 +952,6 @@ static void gui_display_settings()
if (ImGui::BeginTabItem("Video"))
{
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding);
int renderer = settings.pvr.rend == 3 ? 2 : settings.rend.PerStripSorting ? 1 : 0;
#if HOST_OS != OS_DARWIN
bool has_per_pixel = !theGLContext.IsGLES() && theGLContext.GetMajorVersion() >= 4 && !vulkan;
#else
@ -960,6 +959,7 @@ static void gui_display_settings()
#endif
if (ImGui::CollapsingHeader("Transparent Sorting", ImGuiTreeNodeFlags_DefaultOpen))
{
int renderer = pvr_rend == 3 ? 2 : settings.rend.PerStripSorting ? 1 : 0;
ImGui::Columns(has_per_pixel ? 3 : 2, "renderers", false);
ImGui::RadioButton("Per Triangle", &renderer, 0);
ImGui::SameLine();
@ -980,16 +980,16 @@ static void gui_display_settings()
{
case 0:
if (settings.pvr.rend == 3)
settings.pvr.rend = 0;
pvr_rend = 0;
settings.rend.PerStripSorting = false;
break;
case 1:
if (settings.pvr.rend == 3)
settings.pvr.rend = 0;
pvr_rend = 0;
settings.rend.PerStripSorting = true;
break;
case 2:
settings.pvr.rend = 3;
pvr_rend = 3;
break;
}
}
@ -1348,8 +1348,8 @@ static void gui_display_settings()
ImGui_impl_RenderDrawData(ImGui::GetDrawData(), false);
if (vulkan ^ (settings.pvr.rend == 4))
renderer = settings.pvr.rend == 4 ? 0 : 4;
renderer_changed = renderer;
pvr_rend = settings.pvr.rend == 4 ? 0 : 4;
renderer_changed = pvr_rend;
settings.dynarec.Enable = (bool)dynarec_enabled;
}