//#version 420 // Keep it for text editor detection #ifndef VS_BPPZ #define VS_BPPZ 0 #define VS_TME 1 #define VS_FST 1 #define VS_LOGZ 0 #endif #ifdef VERTEX_SHADER layout(location = 0) in vec2 i_st; layout(location = 2) in vec4 i_c; layout(location = 3) in float i_q; layout(location = 4) in uvec2 i_p; layout(location = 5) in uint i_z; layout(location = 6) in uvec2 i_uv; layout(location = 7) in vec4 i_f; out SHADER { vec4 t; vec4 c; flat vec4 fc; } VSout; #define VSout_t (VSout.t) #define VSout_c (VSout.c) #define VSout_fc (VSout.fc) out gl_PerVertex { invariant vec4 gl_Position; float gl_PointSize; #if !pGL_ES float gl_ClipDistance[]; #endif }; layout(std140, binding = 20) uniform cb20 { vec2 VertexScale; vec2 VertexOffset; vec2 TextureScale; }; #ifdef ZERO_TO_ONE_DEPTH const float exp_min32 = exp2(-32.0f); #else const float exp_min31 = exp2(-31.0f); #endif #ifdef SUBROUTINE_GL40 // Function pointer type subroutine void TextureCoordType(void); // a function pointer variable layout(location = 0) subroutine uniform TextureCoordType texture_coord; layout(index = 0) subroutine(TextureCoordType) void tme_0() { VSout_t.xy = vec2(0.0f, 0.0f); VSout_t.w = 1.0f; } layout(index = 1) subroutine(TextureCoordType) void tme_1_fst_0() { VSout_t.xy = i_st; VSout_t.w = i_q; } layout(index = 2) subroutine(TextureCoordType) void tme_1_fst_1() { VSout_t.xy = vec2(i_uv) * TextureScale; VSout_t.w = 1.0f; } #else void texture_coord() { if(VS_TME != 0) { if(VS_FST != 0) { if (VS_WILDHACK == 1) { VSout_t.xy = vec2(i_uv & uvec2(0x3FEF, 0x3FEF)) * TextureScale; } else { VSout_t.xy = vec2(i_uv) * TextureScale; } VSout_t.w = 1.0f; } else { VSout_t.xy = i_st; VSout_t.w = i_q; } } else { VSout_t.xy = vec2(0.0f, 0.0f); VSout_t.w = 1.0f; } } #endif void vs_main() { highp uint z; if(VS_BPPZ == 1) // 24 z = i_z & uint(0xffffff); else if(VS_BPPZ == 2) // 16 z = i_z & uint(0xffff); else z = i_z; // pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go) // example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty // input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel // example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133 vec4 p; p.xy = vec2(i_p) - vec2(0.05f, 0.05f); p.xy = p.xy * VertexScale - VertexOffset; p.w = 1.0f; #ifdef ZERO_TO_ONE_DEPTH if(VS_LOGZ == 1) { p.z = log2(float(1u+z)) / 32.0f; } else { p.z = float(z) * exp_min32; } #else if(VS_LOGZ == 1) { p.z = log2(float(1u+z)) / 31.0f - 1.0f; } else { p.z = float(z) * exp_min31 - 1.0f; } #endif gl_Position = p; texture_coord(); VSout_c = i_c; VSout_fc = i_c; VSout_t.z = i_f.r; } #endif #ifdef GEOMETRY_SHADER #ifndef GS_SPRITE #define GS_SPRITE 0 #endif in gl_PerVertex { invariant vec4 gl_Position; float gl_PointSize; #if !pGL_ES float gl_ClipDistance[]; #endif } gl_in[]; //in int gl_PrimitiveIDIn; out gl_PerVertex { vec4 gl_Position; float gl_PointSize; #if !pGL_ES float gl_ClipDistance[]; #endif }; //out int gl_PrimitiveID; in SHADER { vec4 t; vec4 c; flat vec4 fc; } GSin[]; out SHADER { vec4 t; vec4 c; flat vec4 fc; #if GS_SPRITE > 0 flat vec4 flat_T; flat vec2 flat_P; vec2 alpha; #endif } GSout; layout(std140, binding = 22) uniform cb22 { vec4 rt_size; }; struct vertex { vec4 t; vec4 c; vec2 a; }; void out_vertex(in vertex v) { GSout.t = v.t; GSout.c = v.c; #if GS_SPRITE > 0 GSout.alpha = v.a; #endif gl_PrimitiveID = gl_PrimitiveIDIn; EmitVertex(); } void out_flat(in vec2 dp) { // Flat output GSout.fc = GSin[1].fc; #if GS_SPRITE > 0 GSout.flat_T = vec4(GSin[0].t.x, GSin[1].t.x, GSin[0].t.y, GSin[1].t.y); GSout.flat_P = 1.0f / dp; #endif } layout(lines) in; layout(triangle_strip, max_vertices = 6) out; void gs_main() { // Rescale from -1 1 to 0:1 (require window size) #if GS_SPRITE > 0 vec2 dp = (gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy) * rt_size.xy; #else vec2 dp = vec2(0.0f, 0.0f); #endif // left top => GSin[0]; // right bottom => GSin[1]; vertex rb = vertex(GSin[1].t, GSin[1].c, dp); vertex lt = vertex(GSin[0].t, GSin[0].c, vec2(0.0f, 0.0f)); vec4 rb_p = gl_in[1].gl_Position; vec4 lb_p = gl_in[1].gl_Position; vec4 rt_p = gl_in[1].gl_Position; vec4 lt_p = gl_in[0].gl_Position; // flat depth lt_p.z = rb_p.z; // flat fog and texture perspective lt.t.zw = rb.t.zw; // flat color lt.c = rb.c; // Swap texture and position coordinate vertex lb = rb; lb_p.x = lt_p.x; lb.t.x = lt.t.x; lb.a.x = lt.a.x; vertex rt = rb; rt_p.y = lt_p.y; rt.t.y = lt.t.y; rt.a.y = lt.a.y; // Triangle 1 gl_Position = lt_p; out_vertex(lt); gl_Position = lb_p; out_vertex(lb); gl_Position = rt_p; out_flat(dp); out_vertex(rt); EndPrimitive(); // Triangle 2 gl_Position = lb_p; out_vertex(lb); gl_Position = rt_p; out_vertex(rt); gl_Position = rb_p; out_flat(dp); out_vertex(rb); EndPrimitive(); } #endif