diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index 6bd560274..f120adbc9 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -22,6 +22,9 @@ int fbdev = -1; #endif #endif +#ifndef GL_RED +#define GL_RED 0x1903 +#endif #ifndef GL_MAJOR_VERSION #define GL_MAJOR_VERSION 0x821B #endif @@ -89,7 +92,6 @@ const char* VertexShaderSource = /* Vertex constants*/ \n\ uniform highp vec4 scale; \n\ uniform highp vec4 depth_scale; \n\ -uniform highp float sp_FOG_DENSITY; \n\ /* Vertex input */ \n\ in highp vec4 in_pos; \n\ in lowp vec4 in_base; \n\ @@ -99,15 +101,12 @@ in mediump vec2 in_uv; \n\ out lowp vec4 vtx_base; \n\ out lowp vec4 vtx_offs; \n\ out mediump vec2 vtx_uv; \n\ -out highp vec3 vtx_xyz; \n\ void main() \n\ { \n\ vtx_base=in_base; \n\ vtx_offs=in_offs; \n\ vtx_uv=in_uv; \n\ vec4 vpos=in_pos; \n\ - vtx_xyz.xy = vpos.xy; \n\ - vtx_xyz.z = vpos.z*sp_FOG_DENSITY; \n\ vpos.w=1.0/vpos.z; \n\ #if TARGET_GL != GLES2 \n\ if (vpos.w < 0.0) { \n\ @@ -254,12 +253,15 @@ const char* PixelPipelineShader = #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\ /* Shader program params*/ \n\ @@ -267,17 +269,20 @@ out highp vec4 FragColor; \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 vec2 sp_LOG_FOG_COEFS; \n\ +uniform highp float sp_FOG_DENSITY; \n\ uniform sampler2D tex,fog_table; \n\ /* Vertex input*/ \n\ in lowp vec4 vtx_base; \n\ in lowp vec4 vtx_offs; \n\ in mediump vec2 vtx_uv; \n\ -in highp vec3 vtx_xyz; \n\ -lowp float fog_mode2(highp float val) \n\ +lowp float fog_mode2(highp float w) \n\ { \n\ - highp float fog_idx=clamp(val,0.0,127.99); \n\ - return clamp(sp_LOG_FOG_COEFS.y*log2(fog_idx)+sp_LOG_FOG_COEFS.x,0.001,1.0); //the clamp is required due to yet another bug !\n\ + highp float z = clamp(w * 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\ void main() \n\ { \n\ @@ -299,7 +304,7 @@ void main() \n\ color.a=1.0; \n\ #endif\n\ #if pp_FogCtrl==3 \n\ - color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\ + color=vec4(sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\ #endif\n\ #if pp_Texture==1 \n\ { \n\ @@ -343,7 +348,7 @@ void main() \n\ #endif\n\ #if pp_FogCtrl==0 \n\ { \n\ - color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(vtx_xyz.z)); \n\ + color.rgb=mix(color.rgb,sp_FOG_COL_RAM.rgb,fog_mode2(gl_FragCoord.w)); \n\ } \n\ #endif\n\ #if cp_AlphaTest == 1 \n\ @@ -353,7 +358,6 @@ void main() \n\ else \n\ color.a = 1.0; \n\ #endif \n\ - //color.rgb=vec3(vtx_xyz.z/255.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\ @@ -422,6 +426,7 @@ gl_ctx gl; int screen_width; int screen_height; +GLuint fogTextureId; #if (HOST_OS != OS_DARWIN) && !defined(TARGET_NACL32) #if defined(GLES) && !defined(USE_SDL) @@ -749,6 +754,7 @@ void findGLVersion() gl.gl_version = "GLES2"; gl.glsl_version_header = ""; } + gl.fog_image_format = GL_ALPHA; } else { @@ -757,11 +763,13 @@ void findGLVersion() { gl.gl_version = "GL3"; gl.glsl_version_header = "#version 130"; + gl.fog_image_format = GL_RED; } else { gl.gl_version = "GL2"; gl.glsl_version_header = "#version 120"; + gl.fog_image_format = GL_ALPHA; } } } @@ -774,7 +782,6 @@ struct ShaderUniforms_t float fog_den_float; float ps_FOG_COL_RAM[3]; float ps_FOG_COL_VERT[3]; - float fog_coefs[2]; void Set(PipelineShader* s) { @@ -795,9 +802,6 @@ struct ShaderUniforms_t if (s->sp_FOG_COL_VERT!=-1) glUniform3fv( s->sp_FOG_COL_VERT, 1, ps_FOG_COL_VERT); - - if (s->sp_LOG_FOG_COEFS!=-1) - glUniform2fv(s->sp_LOG_FOG_COEFS,1, fog_coefs); } } ShaderUniforms; @@ -936,14 +940,15 @@ bool CompilePipelineShader( PipelineShader* s) if (s->pp_FogCtrl==0 || s->pp_FogCtrl==3) { s->sp_FOG_COL_RAM=glGetUniformLocation(s->program, "sp_FOG_COL_RAM"); - s->sp_LOG_FOG_COEFS=glGetUniformLocation(s->program, "sp_LOG_FOG_COEFS"); } else { s->sp_FOG_COL_RAM=-1; - s->sp_LOG_FOG_COEFS=-1; } - + // Setup texture 1 as the fog table + gu = glGetUniformLocation(s->program, "fog_table"); + if (gu != -1) + glUniform1i(gu, 1); ShaderUniforms.Set(s); @@ -1095,70 +1100,35 @@ bool gles_init() return true; } - - -float fog_coefs[]={0,0}; -void tryfit(float* x,float* y) +void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format) { - //y=B*ln(x)+A - - double sylnx=0,sy=0,slnx=0,slnx2=0; - - u32 cnt=0; - - for (int i=0;i<128;i++) + glActiveTexture(texture_slot); + if (fogTextureId == 0) { - int rep=1; - - //discard values clipped to 0 or 1 - if (y[i]==1 && y[i+1]==1) - continue; - - if (i>0 && y[i]==0 && y[i-1]==0) - continue; - - //Add many samples for first and last value (fog-in, fog-out -> important) - if (i>0 && y[i]!=1 && y[i-1]==1) - rep=10000; - - if (y[i]!=0 && y[i+1]==0) - rep=10000; - - for (int j=0;j>4)*(1+(i&15)/16.f); - yvals[i]=fog_table[i*4+1]/255.0f; - } - - tryfit(xvals,yvals); + fog_needs_update = false; + UpdateFogTexture((u8 *)FOG_TABLE, GL_TEXTURE1, gl.fog_image_format); } glUseProgram(gl.modvol_shader.program); diff --git a/core/rend/gles/gles.h b/core/rend/gles/gles.h index 78b2acad2..e15c459fb 100755 --- a/core/rend/gles/gles.h +++ b/core/rend/gles/gles.h @@ -53,7 +53,7 @@ struct PipelineShader GLuint scale,depth_scale; GLuint pp_ClipTest,cp_AlphaTestValue; - GLuint sp_FOG_COL_RAM,sp_FOG_COL_VERT,sp_FOG_DENSITY,sp_LOG_FOG_COEFS; + GLuint sp_FOG_COL_RAM,sp_FOG_COL_VERT,sp_FOG_DENSITY; // u32 cp_AlphaTest; s32 pp_ClipTestMode; @@ -101,7 +101,7 @@ struct gl_ctx const char *glsl_version_header; int gl_major; bool is_gles; - + GLuint fog_image_format; //GLuint matrix; };